|
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