Whyever **not** declare a function to be `constexpr`?

Lars picture Lars · Feb 25, 2011 · Viewed 15.6k times · Source

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.

Answer

Anthony Williams picture Anthony Williams · Feb 25, 2011

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.