Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to understand the definition of "manifestly constant-evaluated"?

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 and false 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?

like image 286
Brian Bi Avatar asked Dec 23 '20 19:12

Brian Bi


1 Answers

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?

like image 146
Barry Avatar answered Oct 18 '22 02:10

Barry