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.
constexpr
when aconstexpr
function is called with non-constexp arguments. Otherwise functions likesize
instd::bitset
obviously would make no sense to beconstexpr
. – Bernersconstexpr
if the output is not explicitlyconstexpr
, regardless of whether the inputs are. Though I'm not sure if that is what's intended by the standard, it does not make any sense to me. For example, assigning aconstexpr
function's return value to aconst int
will cause the function to appear in the binary and be executed, whereas assigning it to anenum
(with the same inputs!) just defines an enumeration value and generates no code at all. – Triplicate