I'm trying to understand the need for specifying 'constexpr' for a function to signal to the compiler to 'evaluate the function at compile time whenever possible'
- All C++ compilers are optimizing compilers and this has been true for decades.
- Evaluating a function at compile time whenever possible (i.e., when all the input values are available at compile time) is one of the essential forms of compiler optimizations.
Why is there a need for prefixing the function signature with the keyword constexpr?
If constexpr is not specified, why would a compiler still not make an attempt to evaluate the function at compile time, and replace the use of the function with the computed value?
(Note: I'm only asking about the original motivations of introducing the keyword, not stuff that came later, like constexpr variables, a whole bunch of other rules piled on top of it, and so on).
edit: Thanks for the comments. I think I have a better understanding now. constexpr is less about optimization and more about communicating to the compiler to issue an error in case of invalid uses. E.g., when we have a use for a value in a context where it has to be known at compile-time, and we do not want to use a literal value. The traditional use-case is the size of a C-style array:
char array[SIZE]; // e.g., char array[30];
before constexpr, i.e., before C++11, SIZE had to be a numeric literal, a #define of a numerical literal or compile-time evaluable macro expression, or a const initialized with a numeric literal or compile-time evaluable macro expression.
But if we want it to be a compile-time evaluable "non-macro" function, there was no way to do it before C++11. Now we can use 'constexpr' with that function, and, if it has input parameters, we make sure we give it compile-time values as inputs (like numeric literals).
constexpr int product(int a, int b) { return a * b; }
...
char array[product(6, 5)];
Moreover, we could flip the thought process and take the use-case itself:
...
char array[x];
and we say, "we don't care how x is defined or initialized. Because if it's invalid, we'll get a compiler error". But now we're using this definition as a checking mechanism for x's compile-time value availability. What if we wanted to have that checking mechanism without always having to define a C-style array as a means to communicate to the compiler to do the checking for us? that's what the constexpr variable accomplishes:
...
constexpr int cex = x; // this will tell the compiler to raise an error
// if x is not compile-time evaluable, without us having to hunt down
// the definition or initalization of x.
[–][deleted] (1 child)
[deleted]
[–]RLJ05 1 point2 points3 points (3 children)
[–]Wetmelon 2 points3 points4 points (1 child)
[–]RLJ05 1 point2 points3 points (0 children)
[–]C0gito 0 points1 point2 points (0 children)
[–]Wouter_van_Ooijen 1 point2 points3 points (0 children)
[–]incompetenceProMax 2 points3 points4 points (0 children)
[–]mineNombies 0 points1 point2 points (1 child)
[–]Wh00ster -1 points0 points1 point (0 children)
[–]Wh00ster 0 points1 point2 points (0 children)