1

This is a follow up question to this one.

From one of the answers in the question linked, it makes sense that the purpose of declaring a variable as constexpr is not truly to inform the compiler of the possibility of using that variable as a constant expression (although this is the end behavior of the compiler) but rather to convey to other programmers the intent that the variable can be used in a constant expression. My question is whether there is any benefit, performance or otherwise, to declaring a variable as constexpr if the variable is not intended to be used in a constant expression (e.g. a constant member variable of a class which only appears in non-constant expressions with other non-const member variables). Also assume that this is not for an embedded system.

I work with code where the previous developers seem to use constexpr like it's candy even when it's not clear that the intent is for the variable to be used in a constant expression (like in the example from the previous paragraph). I want to know if they knew something that I don't.

Adam Sperry
  • 283
  • 1
  • 9
  • Well, it indicates as a non changable constant and the compiler will complain if you try, much like `const` does. Plain usage of `const` doesn't guarantee evaluation at compile time though. – πάντα ῥεῖ Mar 06 '19 at 22:17
  • I call it future proofing. You might not intend to use it at compile time now, but who knows what you'll need 10 years from know. If it can be a `constexpr`, might as well make it one. – NathanOliver Mar 06 '19 at 22:18
  • Is future proofing the only benefit? On all other metrics, are `const` and `constexpr` considered the same? – Adam Sperry Mar 06 '19 at 22:22
  • @AdamSperry AFAIK; no, `const` is declared at compile and it prevents the changing of runtime evaluation. `constexpr` is declared and evaluated both at compile time. In the sense that the values of a named variable or function can not be modified then yes they are equivalent. – Francis Cugler Mar 06 '19 at 22:44

2 Answers2

1

but rather to convey to other programmers the intent that the variable can be used in a constant expression.

This is a matter of opinion but I beg to differ.

In principle, I think it is better to make everything that can be known and computed at compile time a constexpr. The fact that it can also be used in constant expressions is a side benefit. Use of constexpr may have performance related benefits too.

The key point I want to make is that "the value is known at compile time" is a characteristic of the variable/data. It is better to capture that characteristic by using a language provided feature. The only time one could justify not using it will be if there are any adverse side effects.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • I see your point, but what about cases like in the answer by Filip Roséen - refp to the question I linked? The function `f()` certainly could have been a `constexper` before the optimization, but afterward it cannot. This would break any code that uses `f()` in a `constexper`. I understand that there is some opinion to whether `constexper` should be used. My question is whether there are other benefits besides the ones already discussed. You mention performance benefits. Are these for sure or are you just postulating? – Adam Sperry Mar 06 '19 at 23:14
  • @AdamSperry, I am speculating about performance. Coincidentally, both of us express the same idea. What I call *the characteristic of the variable/data* he calls *intent*. – R Sahu Mar 06 '19 at 23:22
  • @R Sahu, Thank you – Adam Sperry Mar 06 '19 at 23:26
0

Yes, constexpr variables are useful for more than just conveying intent and using in other constant expressions.

If you mark a variable constexpr, the compiler will enforce that it itself is initialized with a constant expression. You can use this to make sure that the things you expect to be evaluated at compile time actually are. For example:

constexpr int constexpr_function() { return 123; }
int expensive_runtime_function() { return 123; }

void f()
{
    constexpr int good1 = constexpr_function(); // OK.
    // constexpr int good2 = expensive_runtime_function(); // Good: error.

    const int bad1 = constexpr_function(); // OK.
    const int bad2 = expensive_runtime_function(); // Bad: unexpected runtime cost.
}
Maxpm
  • 24,113
  • 33
  • 111
  • 170