Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

One definition rule about class member access expression

In N4296, 3.2 [basic.def.odr]p3:

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.

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:
  1. Either ex is not potentially evaluated, or
  2. All of the following must be fulfilled:
    1. "applying the lvalue-to-rvalue conversion to x yields a constant expression that does not invoke any non-trivial functions" and
    2. "ex is an element of the set of potential results of an expression e" and either of the following holds:
      1. "either the lvalue-to-rvalue conversion is applied to e"
      2. "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 expression ex 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 expression e, 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
like image 850
stackcpp Avatar asked Oct 20 '22 07:10

stackcpp


1 Answers

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.

like image 191
ecatmur Avatar answered Nov 15 '22 01:11

ecatmur