5

在 N4296, 3.2 [basic.def.odr]p3 中:

x名称显示为潜在求值表达式的变量ex被 odr 使用,ex除非应用左值到右值转换来x生成不调用任何非平凡函数的常量表达式,并且如果x是对象,ex则它是表达式 的潜在结果集e,其中应用了左值到右值的转换e,或者e是丢弃值表达式。

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

1 从这里“试图理解 C++14 (N4140) 中的 [basic.def.odr]/2

让我们把它分成几个步骤:在表达式 `ex` 中出现变量 `x` 构成了 odr-use,除非:
  1. 要么 ex没有潜在的评估,要么
  2. 必须满足以下所有条件:
    1. “应用左值到右值的转换来x产生一个不调用任何非平凡函数的常量表达式”
    2. ex是表达式的潜在结果集合中的一个元素e ,并且以下任一项成立
      1. 要么左值到右值的转换应用于e
      2. " or e是一个弃值表达式"

和 2 来自 cppreference http://en.cppreference.com/w/cpp/language/definition

除非以下任何一项为真,否则x潜在求值表达式中的变量ex是 odr-used :

  • 应用左值到右值的转换来x产生一个不调用非平凡函数的常量表达式

  • x是一个对象,而 ex 是较大表达式的潜在结果之一e,其中较大的表达式要么是丢弃值表达式,要么是左值到右值的转换

关于两个规则的第一个答案是and,另一个是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
4

1 回答 1

3

cppreference错误的;从标准中的语言(无论哪个版本)可以清楚地看出,这两个子条款都必须遵守。我已经纠正了。

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

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

s如果没有or的定义,gcc 可能没问题x,但没有要求实现诊断每个 odr 违规。

于 2015-07-13T11:17:10.993 回答