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
true
during the evaluation of such expressions andfalse
otherwise.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
e
is 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