One definition rule about class member access expression

拜拜、爱过 提交于 2019-12-10 14:14:12

问题


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

回答1:


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.



来源:https://stackoverflow.com/questions/31381563/one-definition-rule-about-class-member-access-expression

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!