In N4296, 3.2 [basic.def.odr]p3:
A variable
x
whose name appears as a potentially-evaluated expressionex
is odr-used byex
unless applying the lvalue-to-rvalue conversion tox
yields a constant expression that does not invoke any non-trivial functions and, ifx
is an object,ex
is an element of the set of potential results of an expressione
, where either the lvalue-to-rvalue conversion is applied toe
, ore
is 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
ex
is not potentially evaluated, or- All of the following must be fulfilled:
- "applying the lvalue-to-rvalue conversion to
x
yields a constant expression that does not invoke any non-trivial functions" and- "
ex
is 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
e
is a discarded-value expression"
and 2 from cppreference http://en.cppreference.com/w/cpp/language/definition
a variable
x
in a potentially-evaluated expressionex
is odr-used unless any of the following is true:
applying lvalue-to-rvalue conversion to
x
yields a constant expression that doesn't invoke non-trivial functions
x
is 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