|
441 | 441 | A variable is named by an expression
|
442 | 442 | if the expression is an \grammarterm{id-expression} that denotes it.
|
443 | 443 | A variable \tcode{x} that is named by a
|
444 |
| -potentially-evaluated expression $E$ |
445 |
| -is \defnx{odr-used}{odr-use} by $E$ unless |
| 444 | +potentially-evaluated expression $N$ |
| 445 | +that appears at a point $P$ |
| 446 | +is \defnx{odr-used}{odr-use} by $N$ unless |
446 | 447 | \begin{itemize}
|
447 | 448 | \item
|
448 |
| - \tcode{x} is a reference that is |
449 |
| - usable in constant expressions\iref{expr.const}, or |
| 449 | +\tcode{x} is a reference |
| 450 | +that is usable in constant expressions at $P$\iref{expr.const} or |
450 | 451 | \item
|
451 |
| - \tcode{x} is a variable of non-reference type that is |
452 |
| - usable in constant expressions and has no mutable subobjects, and |
453 |
| - $E$ is an element of the set of potential results of an expression |
454 |
| - of non-volatile-qualified non-class type |
455 |
| - to which the lvalue-to-rvalue conversion\iref{conv.lval} is applied, or |
| 452 | +$N$ is an element of the set of potential results of an expression $E$, where |
| 453 | +\begin{itemize} |
| 454 | +\item |
| 455 | +$E$ is a discarded-value expression\iref{expr.context} |
| 456 | +to which the lvalue-to-rvalue conversion is not applied or |
| 457 | +\item |
| 458 | +\tcode{x} is a non-volatile object |
| 459 | +that is usable in constant expressions at $P$ and |
| 460 | +has no mutable subobjects and |
| 461 | +\begin{itemize} |
| 462 | +\item |
| 463 | +$E$ is a class member access expression\iref{expr.ref} |
| 464 | +naming a non-static data member of reference type and |
| 465 | +whose object expression has non-volatile-qualified type or |
456 | 466 | \item
|
457 |
| - \tcode{x} is a variable of non-reference type, and |
458 |
| - $E$ is an element of the set of potential results |
459 |
| - of a discarded-value expression\iref{expr.context} |
460 |
| - to which the lvalue-to-rvalue conversion is not applied. |
| 467 | +the lvalue-to-rvalue conversion\iref{conv.lval} is applied to $E$ and |
| 468 | +$E$ has non-volatile-qualified non-class type |
461 | 469 | \end{itemize}
|
| 470 | +\end{itemize} |
| 471 | +\end{itemize} |
| 472 | +\begin{example} |
| 473 | +\begin{codeblock} |
| 474 | +int f(int); |
| 475 | +int g(int&); |
| 476 | +struct A { |
| 477 | + int x; |
| 478 | +}; |
| 479 | +struct B { |
| 480 | + int& r; |
| 481 | +}; |
| 482 | +int h(bool cond) { |
| 483 | + constexpr A a = {1}; |
| 484 | + constexpr const volatile A& r = a; // odr-uses \tcode{a} |
| 485 | + int _ = f(cond ? a.x : r.x); // does not odr-use \tcode{a} or \tcode{r} |
| 486 | + int x, y; |
| 487 | + constexpr B b1 = {x}, b2 = {y}; // odr-uses \tcode{x} and \tcode{y} |
| 488 | + int _ = g(cond ? b1.r : b2.r); // does not odr-use \tcode{b1} or \tcode{b2} |
| 489 | + int _ = ((cond ? x : y), 0); // does not odr-use \tcode{x} or \tcode{y} |
| 490 | + return [] { |
| 491 | + return b1.r; // error: \tcode{b1} is odr-used here because the object |
| 492 | + // referred to by \tcode{b1.r} is not constexpr-referenceable here |
| 493 | + }(); |
| 494 | +} |
| 495 | +\end{codeblock} |
| 496 | +\end{example} |
462 | 497 |
|
463 | 498 | \pnum
|
464 | 499 | A structured binding is odr-used if it appears as a potentially-evaluated expression.
|
|
6886 | 6921 | \pnum
|
6887 | 6922 | \indextext{initialization!constant}%
|
6888 | 6923 | \defnx{Constant initialization}{constant initialization} is performed
|
6889 |
| -if a variable or temporary object with static or thread storage duration |
| 6924 | +if a variable with static or thread storage duration |
6890 | 6925 | is constant-initialized\iref{expr.const}.
|
6891 | 6926 | \indextext{initialization!zero-initialization}%
|
6892 | 6927 | If constant initialization is not performed, a variable with static
|
|
0 commit comments