Any function that consists of a return statement only could be declared
constexpr
and thus will allow to be evaluated at compile time if all
arguments are constexpr
and only constexpr
functions are called in its body. Is there any reason not to declare any such function constexpr
?
Example:
constexpr int sum(int x, int y) { return x + y; }
constexpr i = 10;
static_assert(sum(i, 13) == 23, "sum correct");
Could anyone provide an example where declaring a function constexpr
would do any harm?
Some initial thoughts:
Even if there should be no good reason for ever declaring a function
not constexpr
I could imagine that the constexpr
keyword has a
transitional role: its absence in code that does not need compile-time
evaluations would allow compilers that do not implement compile-time
evaluations still to compile that code (but to fail reliably on code
that needs them as made explict by using constexpr
).
But what I do not understand: if there should be no good reason for
ever declaring a function not constexpr
, why is not every function
in the standard library declared constexpr
? (You cannot argue
that it is not done yet because there was not sufficient time yet to
do it, because doing it for all is a no-brainer -- contrary to deciding for every single function if to make it constexpr
or not.)
--- I am aware that N2976
deliberately not requires cstrs for many standard library types such
as the containers as this would be too limitating for possible
implementations. Lets exclude them from the argument and just wonder:
once a type in the standard library actually has a constexpr
cstr, why is not every function operating on it declared constexpr
?
In most cases you also cannot argue that you may prefer not to declare a function constexpr
simply because you do not envisage any compile-time usage: because if others evtl. will use your code, they may see such a use that you do not. (But granted for type trait types and stuff alike, of course.)
So I guess there must be a good reason and a good example for deliberately not declaring a function constexpr
?
(with "every function" I always mean: every function that meets the
requirements for being constexpr
, i.e., is defined as a single
return statement, takes only arguments of types with constexpr
cstrs and calls only constexpr
functions. Since C++14, much more is allowed in the body of such function: e.g., C++14 constexpr functions may use local variables and loops, so an even wider class of functions could be declared constexpr
.)
The question Why does std::forward
discard constexpr
-ness? is a special case of this one.
Functions can only be declared constexpr
if they obey the rules for constexpr
--- no dynamic casts, no memory allocation, no calls to non-constexpr
functions, etc.
Declaring a function in the standard library as constexpr
requires that ALL implementations obey those rules.
Firstly, this requires checking for each function that it can be implemented as constexpr
, which is a long job.
Secondly, this is a big constraint on the implementations, and will outlaw many debugging implementations. It is therefore only worth it if the benefits outweigh the costs, or the requirements are sufficiently tight that the implementation pretty much has to obey the constexpr
rules anyway. Making this evaluation for each function is again a long job.