|
7209 | 7209 | machine\iref{intro.execution}, would evaluate one of the following:
|
7210 | 7210 | \begin{itemize}
|
7211 | 7211 | \item
|
7212 |
| -\keyword{this}\iref{expr.prim.this}, except in a constexpr |
7213 |
| -function\iref{dcl.constexpr} that is being evaluated as part |
7214 |
| -of $E$; |
| 7212 | +\keyword{this}\iref{expr.prim.this}, except |
| 7213 | +\begin{itemize} |
| 7214 | +\item |
| 7215 | +in a constexpr function\iref{dcl.constexpr} |
| 7216 | +that is being evaluated as part of $E$ or |
| 7217 | +\item |
| 7218 | +when appearing as the \grammarterm{postfix-expression} of |
| 7219 | +an implicit or explicit class member access expression\iref{expr.ref}; |
| 7220 | +\end{itemize} |
7215 | 7221 |
|
7216 | 7222 | \item
|
7217 | 7223 | a control flow that passes through
|
|
7236 | 7242 |
|
7237 | 7243 | \item
|
7238 | 7244 | an invocation of a virtual function\iref{class.virtual}
|
7239 |
| -for an object unless |
7240 |
| - \begin{itemize} |
7241 |
| - \item the object is usable in constant expressions or |
7242 |
| - \item its lifetime began within the evaluation of $E$; |
7243 |
| - \end{itemize} |
| 7245 | +for an object whose dynamic type is constexpr-unknown |
7244 | 7246 |
|
7245 | 7247 | \item
|
7246 | 7248 | an expression that would exceed the implementation-defined
|
|
7284 | 7286 | for a union whose active member (if any) is mutable,
|
7285 | 7287 | unless the lifetime of the union object began within the evaluation of $E$;
|
7286 | 7288 |
|
7287 |
| -\item |
7288 |
| -an \grammarterm{id-expression} that refers to a variable or |
7289 |
| -data member of reference type |
7290 |
| -unless the reference has a preceding initialization and either |
7291 |
| -\begin{itemize} |
7292 |
| - \item |
7293 |
| - it is usable in constant expressions or |
7294 |
| - |
7295 |
| - \item |
7296 |
| - its lifetime began within the evaluation of $E$; |
7297 |
| -\end{itemize} |
7298 |
| - |
7299 | 7289 | \item
|
7300 | 7290 | in a \grammarterm{lambda-expression},
|
7301 | 7291 | a reference to \keyword{this} or to a variable with
|
|
7387 | 7377 | a \grammarterm{throw-expression}\iref{expr.throw};
|
7388 | 7378 |
|
7389 | 7379 | \item
|
7390 |
| -a \keyword{dynamic_cast}\iref{expr.dynamic.cast} or \keyword{typeid}\iref{expr.typeid} expression |
| 7380 | +a \keyword{dynamic_cast}\iref{expr.dynamic.cast} or |
| 7381 | +\keyword{typeid}\iref{expr.typeid} expression |
| 7382 | +on a glvalue that refers to an object |
| 7383 | +whose dynamic type is constexpr-unknown or |
7391 | 7384 | that would throw an exception;
|
7392 | 7385 |
|
7393 | 7386 | \item
|
|
7469 | 7462 | the evaluation of the underlying constructor call
|
7470 | 7463 | disqualifies $E$ from being a core constant expression.
|
7471 | 7464 |
|
| 7465 | +\pnum |
| 7466 | +During the evaluation of an expression $E$ as a core constant expression, |
| 7467 | +all \grammarterm{id-expression}s and uses of \tcode{*\keyword{this}} |
| 7468 | +that refer to an object or reference |
| 7469 | +whose lifetime did not begin with the evaluation of $E$ |
| 7470 | +are treated as referring to a specific instance of that object or reference |
| 7471 | +whose lifetime and that of all subobjects (including all union members) |
| 7472 | +includes the entire constant evaluation. |
| 7473 | +For such an object that is not usable in constant expressions, |
| 7474 | +the dynamic type of the object is \defn{constexpr-unknown}. |
| 7475 | +For such a reference that is not usable in constant expressions, |
| 7476 | +the reference is treated as binding to |
| 7477 | +an unspecified object of the referenced type |
| 7478 | +whose lifetime and that of all subobjects includes |
| 7479 | +the entire constant evaluation and whose dynamic type is constexpr-unknown. |
| 7480 | +\begin{example} |
| 7481 | +\begin{codeblock} |
| 7482 | +template <typename T, size_t N> |
| 7483 | +constexpr size_t array_size(T (&)[N]) { |
| 7484 | + return N; |
| 7485 | +} |
| 7486 | + |
| 7487 | +void use_array(int const (&gold_medal_mel)[2]) { |
| 7488 | + constexpr auto gold = array_size(gold_medal_mel); // OK |
| 7489 | +} |
| 7490 | + |
| 7491 | +constexpr auto olympic_mile() { |
| 7492 | + const int ledecky = 1500; |
| 7493 | + return []{ return ledecky; }; |
| 7494 | +} |
| 7495 | +static_assert(olympic_mile()() == 1500); // OK |
| 7496 | + |
| 7497 | +struct Swim { |
| 7498 | + constexpr int phelps() { return 28; } |
| 7499 | + virtual constexpr int lochte() { return 12; } |
| 7500 | + int coughlin = 12; |
| 7501 | +}; |
| 7502 | + |
| 7503 | +constexpr int how_many(Swim& swam) { |
| 7504 | + Swim* p = &swam; |
| 7505 | + return (p + 1 - 1)->phelps(); |
| 7506 | +} |
| 7507 | + |
| 7508 | +void splash(Swim& swam) { |
| 7509 | + static_assert(swam.phelps() == 28); // OK |
| 7510 | + static_assert((&swam)->phelps() == 28); // OK |
| 7511 | + Swim* pswam = &swam; |
| 7512 | + static_assert(pswam->phelps() == 28); // error: lvalue-to-rvalue conversion on a pointer |
| 7513 | + // not usable in constant expressions |
| 7514 | + static_assert(how_many(swam) == 28); // OK |
| 7515 | + static_assert(Swim().lochte() == 12); // OK |
| 7516 | + static_assert(swam.lochte() == 12); // error: invoking virtual function on reference |
| 7517 | + // with constexpr-unknown dynamic type |
| 7518 | + static_assert(swam.coughlin == 12); // error: lvalue-to-rvalue conversion on an object |
| 7519 | + // not usable in constant expressions |
| 7520 | +} |
| 7521 | + |
| 7522 | +extern Swim dc; |
| 7523 | +extern Swim& trident; |
| 7524 | + |
| 7525 | +constexpr auto& sandeno = typeid(dc); // OK, can only be \tcode{typeid(Swim)} |
| 7526 | +constexpr auto& gallagher = typeid(trident); // error: constexpr-unknown dynamic type |
| 7527 | +\end{codeblock} |
| 7528 | +\end{example} |
| 7529 | + |
7472 | 7530 | \pnum
|
7473 | 7531 | An object \tcode{a} is said to have \defnadj{constant}{destruction} if:
|
7474 | 7532 | \begin{itemize}
|
|
7582 | 7640 | object with static storage duration that either is not a temporary object or is
|
7583 | 7641 | a temporary object whose value satisfies the above constraints, or if
|
7584 | 7642 | it is a non-immediate function.
|
| 7643 | +\begin{note} |
| 7644 | +A glvalue core constant expression |
| 7645 | +that either refers to or points to an unspecified object |
| 7646 | +is not a constant expression. |
| 7647 | +\end{note} |
7585 | 7648 | \begin{example}
|
7586 | 7649 | \begin{codeblock}
|
7587 | 7650 | consteval int f() { return 42; }
|
|
0 commit comments