10

Can C++11 compilers (and do they) notice that a function is a constexpr and treat them as such even if they are not declared to be constexpr?

I was demonstrating the use of constexpr to someone using the example straight from the Wikipedia:

int get_five() {return 5;}

int some_value[get_five() + 7]; // Create an array of 12 integers. Ill-formed C++

To my surprise the compiler was OK with it. So, I further changed get_five( ) to take a few int parameters, multiply them and return the result while still not being explicitly declared to be constexpr. The compiler was OK with that as well. It seems that if the compiler can do this there isn't much point to having the restrictions that are required in order to explicitly declare something constexpr.

Arbalest
  • 1,095
  • 11
  • 23
  • 6
    Maybe your compiler supports VLA as an extension. Did you consider that? – David G Apr 01 '13 at 19:03
  • 1
    What compiler is that? – SomeWittyUsername Apr 01 '13 at 19:03
  • 1
    possible duplicate of [In C++ books, array bound must be constant expression, but why the following code works?](http://stackoverflow.com/questions/5947661/in-c-books-array-bound-must-be-constant-expression-but-why-the-following-cod) – Bo Persson Apr 01 '13 at 19:12
  • I am using I am using g++ via MinGW-4.6.1 but also using the -std=c++0x and -pedantic switches. I am looking into installing Clang at the moment, per answer by JC below. @Bo - I am talking about the constexpr keyword, which is (supposed to be) required in the declaration of get_five( ) above. – Arbalest Apr 01 '13 at 20:12
  • @Arbalest - There is no implicit constexpr that I know of, but as Jerry Coffin answers below g++ (depending on exact options set) might allow some C99 features to be used in C++ as well. – Bo Persson Apr 01 '13 at 20:42

3 Answers3

7

On a properly-functioning C++11 compiler, your code would be rejected.

Based on its being accepted, you're almost certainly using gcc (or something that closely emulates its bugs). gcc [depending somewhat on flags] can accept array sizes that aren't constant by any measure (e.g., depend on run-time input from the user) because they support an analog of C99 variable-length arrays in C++.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
3

GCC, as of GCC 12, supports the -fimplicit-constexpr command-line toggle which enables exactly that, for methods marked as inline.

Jean-Michaël Celerier
  • 7,412
  • 3
  • 54
  • 75
  • As interesting as this information is, enabling this flag does not appear to accept the OP's code (tested on [compiler-explorer](https://compiler-explorer.com/z/MaEa3cKoP)). Either that or the `gcc-trunk` on compiler-explorer does not yet have the change, but accepts the flag. – Human-Compiler Mar 24 '22 at 21:39
  • It needs functions to be marked as inline: https://gcc.godbolt.org/z/o81f1q3de ; I edited the answer to add this – Jean-Michaël Celerier Mar 24 '22 at 22:38
  • While this is a welcome addition to the future of C++ development, I am sorry to say that it is not enough. If you do not mark originating data as constexpr on their declarations then the constexpr functions would not be used anyway. What GCC did is merely a measure to save typing effort, not retroactively optimize code! Allowing for greater developer-controlled optimization strategies would hugely benefit software modelling strategies! – rplgn Jan 08 '23 at 08:57
2

A compiler can detect whether or not a function could have been declared with constexpr even when they haven't, for optimization purposes (i.e. computing the result of a function at compile-time). Compilers did that prior to C++11.

But for use in places that requires constant expressions, such as template parameters of integral type, it is against the standard to allow calls to functions that are not declared with the constexpr keyword.

Zyx 2000
  • 1,625
  • 1
  • 12
  • 18
  • 1
    "__A compiler can detect whether or not a function could have been declared with constexpr__" Do you have any reference to back this up? – C. Sederqvist Oct 28 '13 at 23:26
  • 4
    @cseder I find it hard to imagine that any modern compiler wouldn't do it. It is basic knowledge about how compilers work. – Zyx 2000 Oct 29 '13 at 11:52
  • That's hardly evidence. And when you say "modern compilers" I guess you rule out the latest Visual C++ 2013 compiler, because it does not support automatic [memoization](http://en.wikipedia.org/wiki/Memoization). A constexpr is only usable if the result returned from the constexpr function is the same every time and so does not need to include much knowledge about compiling. – C. Sederqvist Oct 29 '13 at 15:16
  • 2
    I never said anything about memoization. There are other ways for compilers to constant expressions. – Zyx 2000 Oct 29 '13 at 17:27
  • I just want to know what facts you have to back up your statement. – C. Sederqvist Oct 30 '13 at 21:53
  • 1
    If you don't want to accept what is common knowledge, then so be it. – Zyx 2000 Oct 30 '13 at 22:15
  • It's obviously not "common knowledge", when nobody has any fulfilling answers to it, you included. Over And Out. – C. Sederqvist Oct 31 '13 at 23:22
  • 1
    Not many people pay attention to 7-months old questions. Read my answer again, and use google. I'm not going to do the work for you. – Zyx 2000 Nov 01 '13 at 10:17
  • I'll just give you the last word in this discussion. It leads nowhere. – C. Sederqvist Nov 02 '13 at 17:39
  • Well, maybe I'll just quote the only accepted answer while I'm at it: On a properly-functioning C++11 compiler, your code would be rejected. – C. Sederqvist Nov 02 '13 at 17:41
  • I think you guys are confused. There is a misunderstanding between MERELY ALLOWING a compiler to change the specification into constexpr and FORCING it according to language rules. The latter allows user-defined functions to be tied into the compilation optimization strategy which is a key benefit. – rplgn Jan 08 '23 at 08:44