In N4296, 3.2 [basic.def.odr]p3:
A variable
xwhose name appears as a potentially-evaluated expressionexis odr-used byexunless applying the lvalue-to-rvalue conversion toxyields a constant expression that does not invoke any non-trivial functions and, ifxis an object,exis an element of the set of potential results of an expressione, where either the lvalue-to-rvalue conversion is applied toe, oreis a discarded-value expression.
How to explain this paragraph? I found two explanation.
1 from here "Trying to understand [basic.def.odr]/2 in C++14 (N4140)"
Let's split this into steps: The occurrence of a variable `x` in an expression `ex` constitutes an odr-use unless:
- Either
exis not potentially evaluated, or- All of the following must be fulfilled:
- "applying the lvalue-to-rvalue conversion to
xyields a constant expression that does not invoke any non-trivial functions" and- "
exis an element of the set of potential results of an expressione" and either of the following holds:
- "either the lvalue-to-rvalue conversion is applied to
e"- "or
eis a discarded-value expression"
and 2 from cppreference http://en.cppreference.com/w/cpp/language/definition
a variable
xin a potentially-evaluated expressionexis odr-used unless any of the following is true:
applying lvalue-to-rvalue conversion to
xyields a constant expression that doesn't invoke non-trivial functions
xis an object and ex is one of the potential results of a larger expressione, where that larger expression is either a discarded-value expression or an lvalue-to-rvalue conversion
First answer about two rules is and, the other is any. Which one is right?
Please split rules into steps to explain this code:
struct S { static const int x = 0; };
extern S s;// no definition of s
int i = s.x;// is s odr-used? is x odr-used?
// gcc 5.1.0 is ok
cppreference is was wrong; it is clear from the language in the standard (whichever version) that both subclauses must hold. I've corrected it.
In your example, s is not a constant expression (C++14: does not satisfy the requirements for appearing in a constant expression) so is odr-used. The second subclause does not arise.
Meanwhile, x is also odr-used, because although it would be possible to use x in a constant expression in an appropriate context (e.g. as an array bound within the definition of S); x is not one of the potential results of the enclosing expression s.x, which is the only enclosing expression subject to either the discarded-value transformation or the lvalue-to-rvalue conversion.
gcc might be OK without a definition of s or x, but there's no requirement that an implementation diagnose every odr violation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With