|
8329 | 8329 |
|
8330 | 8330 | \rSec2[expr.const.core]{Core constant expressions} |
8331 | 8331 |
|
| 8332 | +\pnum |
| 8333 | +\indextext{type!constexpr-unknown representation}% |
| 8334 | +A type has \defnadj{constexpr-unknown}{representation} if it |
| 8335 | +\begin{itemize} |
| 8336 | +\item is a union, |
| 8337 | +\item is a pointer or pointer-to-member type, |
| 8338 | +\item is volatile-qualified, |
| 8339 | +\item is a class type with a non-static data member of reference type, or |
| 8340 | +\item |
| 8341 | +has a base class or a non-static member whose |
| 8342 | +type has constexpr-unknown representation. |
| 8343 | +\end{itemize} |
| 8344 | + |
8332 | 8345 | \pnum |
8333 | 8346 | An expression $E$ is a \defnadj{core constant}{expression} |
8334 | 8347 | unless the evaluation of $E$, following the rules of the abstract |
|
8556 | 8569 | relational\iref{expr.rel}, or equality\iref{expr.eq} |
8557 | 8570 | operator where the result is unspecified; |
8558 | 8571 |
|
| 8572 | +\item |
| 8573 | +an equality operator comparing pointers to potentially non-unique objects, |
| 8574 | +if the pointer values of the two operands |
| 8575 | +are associated with different evaluations\iref{basic.compound} and either |
| 8576 | +they can both point to the same offset within |
| 8577 | +the same potentially non-unique object or |
| 8578 | +one of them points to an object whose |
| 8579 | +type has constexpr-unknown representation; |
| 8580 | +\begin{example} |
| 8581 | +\begin{codeblock} |
| 8582 | +constexpr const char *f() { return "foo"; } |
| 8583 | + |
| 8584 | +constexpr bool b1 = +"foo" == "foo"; // error: non-constant |
| 8585 | +constexpr bool b2 = f() == f(); // error: non-constant |
| 8586 | +constexpr const char *p = f(); |
| 8587 | +constexpr bool b3 = p == p; // OK, value of \tcode{b3} is \tcode{true} |
| 8588 | +constexpr bool b4 = "xfoo" + 1 == "foo\0y"; // error: non-constant; string literal |
| 8589 | + // object could contain \tcode{"xfoo\textbackslash{}0y"} |
| 8590 | +constexpr bool b5 = "foo" == "bar" + 0; // OK, value of \tcode{b5} is \tcode{false} |
| 8591 | +constexpr bool b6 = (const char*)"foo" == "oo"; // OK, value of \tcode{b6} is \tcode{false}; offsets would |
| 8592 | + // be different in a merged string literal object |
| 8593 | + |
| 8594 | +constexpr std::initializer_list<int *> il1 = { (int *)nullptr }; |
| 8595 | +constexpr std::initializer_list<unsigned long> il2 = { 0 }; |
| 8596 | +constexpr bool b7 = il1.begin() == (void *)il2.begin(); // error: non-constant |
| 8597 | +\end{codeblock} |
| 8598 | +\end{example} |
| 8599 | + |
8559 | 8600 | \item |
8560 | 8601 | a \keyword{dynamic_cast}\iref{expr.dynamic.cast} or |
8561 | 8602 | \keyword{typeid}\iref{expr.typeid} expression |
|
0 commit comments