|
6488 | 6488 | conditional-expression
|
6489 | 6489 | \end{bnf}
|
6490 | 6490 |
|
| 6491 | +\pnum |
| 6492 | +A \defn{constant initializer} for a variable or temporary object \tcode{o} is |
| 6493 | +an initializer for which interpreting its full-expression |
| 6494 | +as a \grammarterm{constant-expression} results in a constant expression, |
| 6495 | +except that if \tcode{o} is an object, |
| 6496 | +such an initializer may also invoke constexpr constructors |
| 6497 | +for \tcode{o} and its subobjects |
| 6498 | +even if those objects are of non-literal class types. |
| 6499 | +\begin{note} |
| 6500 | +Such a class may have a non-trivial destructor. |
| 6501 | +Within this evaluation, |
| 6502 | +\tcode{std::is_constant_evaluated()}\iref{meta.is_constant_evaluated} |
| 6503 | +returns \tcode{true}. |
| 6504 | +\end{note} |
| 6505 | +A variable is |
| 6506 | +\defnx{usable in constant expressions}{usable in constant expression} after |
| 6507 | +its initializing declaration is encountered if it is a constexpr variable, or |
| 6508 | +it is of reference type or of const-qualified integral or enumeration type, and |
| 6509 | +its initializer is a constant initializer. |
| 6510 | + |
6491 | 6511 | \pnum
|
6492 | 6512 | An expression \tcode{e} is a \defnadj{core constant}{expression}
|
6493 | 6513 | unless the evaluation of \tcode{e}, following the rules of the abstract
|
|
6540 | 6560 | to a complete non-volatile const object with a preceding initialization,
|
6541 | 6561 | initialized with a constant expression, or
|
6542 | 6562 |
|
6543 |
| - \item |
6544 |
| - a non-volatile glvalue that refers to a subobject of a string |
6545 |
| - literal\iref{lex.string}, or |
6546 |
| - |
6547 |
| - \item |
6548 |
| - a non-volatile glvalue that refers to a non-volatile object |
6549 |
| - defined with \tcode{constexpr} or |
6550 |
| - a template parameter object\iref{temp.param}, |
6551 |
| - or that refers to a non-mutable subobject |
6552 |
| - of such an object, or |
6553 |
| - |
6554 | 6563 | \item
|
6555 | 6564 | a non-volatile glvalue of literal type that refers to a non-volatile object
|
6556 | 6565 | whose lifetime began within the evaluation of \tcode{e};
|
|
6579 | 6588 |
|
6580 | 6589 | \begin{itemize}
|
6581 | 6590 | \item
|
6582 |
| - it is initialized with a constant expression or |
| 6591 | + it is usable in constant expressions or |
6583 | 6592 |
|
6584 | 6593 | \item
|
6585 | 6594 | its lifetime began within the evaluation of \tcode{e};
|
|
6835 | 6844 | It is unspecified whether the value of \tcode{f()} will be \tcode{true} or \tcode{false}.
|
6836 | 6845 | \end{example} \end{note}%
|
6837 | 6846 |
|
| 6847 | +\pnum |
| 6848 | +An expression or conversion \tcode{e} is \defn{manifestly constant-evaluated} |
| 6849 | +if it is: |
| 6850 | +\begin{itemize} |
| 6851 | +\item a \grammarterm{constant-expression}, or |
| 6852 | +\item the condition of a constexpr if statement\iref{stmt.if}, or |
| 6853 | +\item the initializer of a constexpr variable\iref{dcl.constexpr}, or |
| 6854 | +\item an immediate invocation, or |
| 6855 | +\item a \grammarterm{constraint-expression}\iref{temp.constr.decl} |
| 6856 | +(possibly one formed from the \grammarterm{constraint-logical-or-expression} |
| 6857 | +of a \grammarterm{requires-clause}), or |
| 6858 | +\item the initializer of a variable |
| 6859 | +that is usable in constant expressions or |
| 6860 | +has constant initialization.\footnote{Testing this condition |
| 6861 | +may involve a trial evaluation of its initializer as described above.} |
| 6862 | +\begin{example} |
| 6863 | +\begin{codeblock} |
| 6864 | +template<bool> struct X {}; |
| 6865 | +X<std::is_constant_evaluated()> x; // type X<true> |
| 6866 | +int y; |
| 6867 | +const int a = std::is_constant_evaluated() ? y : 1; // dynamic initialization to 1 |
| 6868 | +double z[a]; // ill-formed: "a" is not "usable in constant expressions" |
| 6869 | +const int b = std::is_constant_evaluated() ? 2 : y; // static initialization to 2 |
| 6870 | +int c = y + (std::is_constant_evaluated() ? 2 : y); // dynamic initialization to y+y |
| 6871 | + |
| 6872 | +constexpr int f() { |
| 6873 | + const int n = std::is_constant_evaluated() ? 13 : 17; // n == 13 |
| 6874 | + int m = std::is_constant_evaluated() ? 13 : 17; // m might be 13 or 17 (see below) |
| 6875 | + char arr[n] = {}; // char[13] |
| 6876 | + return m + sizeof(arr); |
| 6877 | +} |
| 6878 | +int p = f(); // m == 13; initialized to 26 |
| 6879 | +int q = p + f(); // m == 17 for this call; initialized to 56 |
| 6880 | +\end{codeblock} |
| 6881 | +\end{example} |
| 6882 | +\end{itemize} |
| 6883 | + |
6838 | 6884 | \pnum
|
6839 | 6885 | \indextext{expression!potentially constant evaluated}%
|
6840 | 6886 | An expression is \defn{potentially constant evaluated}
|
|
0 commit comments