一条关于class成员访问表达式的定义规则

One definition rule about class member access expression

在 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.

这一段怎么解释?我找到了两个解释。

1 从这里“

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"

和 2 个来自 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

关于两条规则的第一个答案是,另一个是any。哪一个是正确的?

请将规则分成几步来解释这段代码:

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 是错误的;从标准(无论哪个版本)中的语言可以清楚地看出,这两个子条款都必须适用。我已经更正了。

在您的示例中,s 不是常量表达式(C++14:不满足出现在常量表达式中的要求),因此使用了 odr。第二条没有出现。

同时,x 也被 odr 使用,因为尽管可以在适当的上下文中的常量表达式中使用 x(例如,作为数组绑定在 S); x 不是封闭表达式 s.x 的潜在结果之一,它是唯一受丢弃值转换或左值到右值转换影响的封闭表达式。

gcc 在没有定义 sx 的情况下可能没问题,但不要求实现诊断每个 odr 违规。