P0595 introduced the std::is_constant_evaluated() function. The paper discusses how there are some situations where the containing expression is a constant expression, but one that the compiler is not required to evaluate at compile time. The example given is:
constexpr double power(double b, int x) {
  if (std::is_constant_evaluated() && x >= 0) {
    // ...
    // return r;
  } else {
    // Let the code generator figure it out.
    return std::pow(b, (double)x);
  }
}
double thousand() {
  return power(10.0, 3);
}
The compiler may evaluate power(10.0, 3) at compile time, but is not required to. Therefore, is_constant_evaluated returns false.
The paper therefore introduces a concept of "manifestly constant-evaluated":
Our approach is to precisely identify a set of expressions that are "manifestly constant-evaluated" (a new technical phrase) and specify that our new function returns
trueduring the evaluation of such expressions andfalseotherwise.Specifically, we include two kinds of expressions in our set of expressions "manifestly constant-evaluated". The first kind is straightforward: Expressions in contexts where the standard already requires a constant result, such as the dimension of an array or the initializer of a constexpr variable. ...
This makes sense to me. However, the actual wording in the standard confuses me:
An expression or conversion
eis manifestly constant-evaluated if it is:
- a constant-expression, or ...
In other words, the standard specifies that all constant expressions are manifestly constant-evaluated, which (to me) does not seem to incorporate the requirement that the expression appears in a context where a constant expression is required. The proposal remarks that power(10.0, 3) is a core constant expression, which is also my understanding; this makes it a constant expression. If all constant expressions are manifestly constant-evaluated, then it seems that is_constant_evaluated must return true here.
How should I understand the definition in the standard so that it has a precise meaning that is consistent with the intent of the proposal?
This is my favorite. It doesn't say " a constant expression." It says "a constant-expression."†
constant-expression is a grammar term. It's a stand-in for those places in C++ grammar where a constant expression is mandated.
For instance, the grammar (specifically, the grammar) for a template-argument is constant-expression (or a type-id or an id-expression), so this rule means that when evaluating a constant-expression that appears as a template-argument, that evaluation is manifestly constant-evaluated.
In contrast, the grammar in if constexpr does not take a constant-expression, it just takes a condition. So this bullet isn't enough to cover if constexpr, which is why there is a special extra bullet to cover "the condition of a constexpr if statement."
† Imagine having to answer this question verbally. You can hear the hyphen, right?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With