7 Expressions [expr]

7.7 Constant evaluation [expr.const]

7.7.7 Further definitions [expr.const.defns]

An expression or conversion is manifestly constant-evaluated if it is
  • a constant-expression, or
  • the condition of a constexpr if statement ([stmt.if]), or
  • an immediate invocation, or
  • the result of substitution into an atomic constraint expression to determine whether it is satisfied ([temp.constr.atomic]), or
  • the initializer of a variable that is usable in constant expressions or has constant initialization ([basic.start.static]).65
    [Example 1: template<bool> struct X {}; X<std::is_constant_evaluated()> x; // type X<true> int y; const int a = std::is_constant_evaluated() ? y : 1; // dynamic initialization to 1 double z[a]; // error: a is not usable // in constant expressions const int b = std::is_constant_evaluated() ? 2 : y; // static initialization to 2 int c = y + (std::is_constant_evaluated() ? 2 : y); // dynamic initialization to y+y constexpr int f() { const int n = std::is_constant_evaluated() ? 13 : 17; // n is 13 int m = std::is_constant_evaluated() ? 13 : 17; // m can be 13 or 17 (see below) char arr[n] = {}; // char[13] return m + sizeof(arr); } int p = f(); // m is 13; initialized to 26 int q = p + f(); // m is 17 for this call; initialized to 56 — end example]
[Note 1: 
Except for a static_assert-message, a manifestly constant-evaluated expression is evaluated even in an unevaluated operand ([expr.context]).
— end note]
An expression or conversion is potentially constant evaluated if it is:
A function or variable is needed for constant evaluation if it is:
  • a constexpr function that is named by an expression that is potentially constant evaluated, or
  • a potentially-constant variable named by a potentially constant evaluated expression.
An object a is said to have constant destruction if
  • it is not of class type nor (possibly multidimensional) array thereof, or
  • it is of class type or (possibly multidimensional) array thereof, that class type has a constexpr destructor ([dcl.constexpr]), and for a hypothetical expression E whose only effect is to destroy a, E would be a core constant expression if the lifetime of a and its non-mutable subobjects (but not its mutable subobjects) were considered to start within E.
65)65)
Testing this condition can involve a trial evaluation of its initializer, with evaluations of contract assertions using the ignore evaluation semantic ([basic.contract.eval]), as described above.
66)66)
In some cases, constant evaluation is needed to determine whether a narrowing conversion is performed ([dcl.init.list]).
67)67)
In some cases, constant evaluation is needed to determine whether such an expression is value-dependent ([temp.dep.constexpr]).