Reputation: 7369
struct S { static const int x = 0; };
int main(){
S obj;
int v = obj.x;
}
Consider the above code, Is obj.x
an odr-use? According to look at the section of basic.def.odr#3
A variable x whose name appears as a potentially-evaluated expression ex is odr-used by ex unless applying the lvalue-to-rvalue conversion to x yields a constant expression that does not invoke any non-trivial functions and, if x is an object, ex is an element of the set of potential results of an expression e, where either the lvalue-to-rvalue conversion is applied to e, or e is a discarded-value expression.
We have such analysis as the following:
In my code, the variable name is x, which is the x in the above quote, and the expression obj.x
is the ex in the quote. So, Is obj.x
a potentially-evaluated expression? Yes, It is, because of this:
An expression is potentially evaluated unless it is an unevaluated operand or a subexpression thereof.
obj.x
is neither an unevaluated operand or a subexpression thereof. So obj.x
is a potentially-evaluated expression. And applying the lvalue-to-rvalue x
indeed yields a constant expression because it's initialized by 0
. What I doubt is the following, that is,
and, if x is an object, ex is an element of the set of potential results of an expression e
we assume the e is obj.x
because lvalue-to-rvalue conversion will apply to it. And what's the set of potential results of e? As following:
basic.def.odr#2
The set of potential results of an expression e is defined as follows:
- If e is a class member access expression, the set contains the potential results of the object expression.
Because e is a class member access expression. hence its set of potential results is object expression.
Abbreviating postfix-expression.id-expression as E1.E2, E1 is called the object expression.
So, the object expression here is obj
, hence the set of potential results of expression obj.x
contains obj
. Obviously, here ex is xand if e is
obj.xthen its set of potential results of expression would be
obj. So, what the expression
eof which the ex
x` is a element of set of potential results? According to look at basic.def.odr#2, I find nothing.
I only pretty sure the lvalue-to-rvalue conversion is applied to obj.x
whole expression. However, all compiler all agree the use of obj.x
is none odr-use. Is it a defect in the standard?
Upvotes: 0
Views: 121
Reputation: 39878
You can’t rely on a compiler to tell you whether it’s an odr-use; if it is, and you haven’t defined the variable, the program is ill-formed, no diagnostic required. That said, it seems like this was a defect in C++17 in that the possibility of referring to a static member variable with a class member access (as opposed to a qualified-id) was overlooked.
Upvotes: 2