13

After relaxing the rules for the constexpr it seems as these functions can be used everywhere. They can be called on both constant (constexpr) and local (mutable) variables as well. So for me it seem as just a hint for the compiler (like inline). I just keep writing it everywhere and remove it if compiler complains. So compiler seems to know everything if a function can be evaluated at compile time or not. Why is it not the default behavior and why do i have to mark anything as constexpr ?

Gzp
  • 141
  • 8
  • For one thing some things are not allowed in a `constexpr` function, even after C++14 relaxations. – 101010 Feb 10 '16 at 07:27
  • Const is a little bit different due to const_cast and other pointer operations. – Gzp Feb 10 '16 at 07:33
  • 2
    Very similar question [here](http://stackoverflow.com/questions/14472359/why-do-we-need-to-mark-functions-as-constexpr/14472576). – Tony Delroy Feb 10 '16 at 10:24

2 Answers2

19

constexpr is an interface guarantee. It means that you can use the function in constant expressions.

Once people can use them in constant expressions, they will. But what if you didn't mean for your function to be used that way? What if you previously had a simple implementation that happened to be constexpr-possible, but in a later revision you need to change that (e.g. because you now need to add log output)?

If you remove the constexpr marker, the usage in constant expressions stops compiling, when it worked before, and the users of your function will be upset. Better to not make the function constexpr in the first place, allowing you more freedom to change it later.

But if the compiler automatically makes your function constexpr, you don't have that choice.

Sebastian Redl
  • 69,373
  • 8
  • 123
  • 157
  • So it's is an (interface) property of an API designed for "external" use (ex. in a library) and it is not for the compiler how to optimize. (Is that right?) If so it'd have been better to reverse the direction and state explicitly that a function is not constexpr, but than backward compatibility were gone (and would have other issues for sure:) ) – Gzp Feb 10 '16 at 08:03
  • 1
    Yes, it's got very little to do with optimisation. Optimisation is done based on what the code actually does, not whether it is marked constexpr or not. If your function is `int f() { return 7; }` and `int x = f()`;the code will be `x = 7;`. Constant propagation has been in compilers for the past 25 years, at least. – Mats Petersson Feb 10 '16 at 08:11
  • @Gzp: constexpr (on functions) has nothing to do with compileroptimizations. – MikeMB Feb 10 '16 at 08:15
  • 1
    Btw.: Constexpr doesn't guarantee you that you can use a function in a constant expression - it can depend on the argument values (even if they are always compile-time constants. – MikeMB Nov 08 '17 at 08:55
2

As pointed here, it makes difference to use function template specialization, defined with constexpr specifier or not in (e.g.) SFINAE context:

The addition of constexpr is causing function templates to be instantiated in unevaluated contexts that otherwise would not.

So, sometimes it would be an undesired behaviour to have all the functions implicitly defined as constexpr.

Tomilov Anatoliy
  • 15,657
  • 10
  • 64
  • 169