关于类成员访问表达式的一个定义规则 [英] One definition rule about class member access expression
问题描述
在N4296,3.2 [basic.def.odr] p3:
变量
x $除非应用左值,否则其名称显示为潜在求值表达式的
ex
是由ex
- 到-rvalue转换为x
产生一个不调用任何非平凡函数的常量表达式,如果x
是一个对象,ex
是表达式e
的一组潜在结果的一个元素,其中lvalue-对e
应用到值转换,或者e
是丢弃值表达式。
如何解释这一段?我发现了两个解释。
1从这里
<我们将这个分解为步骤:表达式中的变量`x`的出现构成一个odr使用,除非:
- 或
-
必须满足以下所有条件:
- 将左值到右值转换应用到
x
产生一个不调用任何非平凡函数的常量表达式 和 -
ex
是表达式e
的潜在结果集合中的一个元素, b>:
- 左值到右值转换应用于
e
- 或
e
是舍弃值
- 左值到右值转换应用于
- 将左值到右值转换应用到
-
将左值到右值转换应用到
x
不调用非平凡函数的表达式 -
x
是一个对象,ex是下列之一较大表达式的潜在结果e
,其中较大的表达式是丢弃值表达式或左值到右值转换 - Either
ex
is not potentially evaluated, or - All of the following must be fulfilled:
- "applying the lvalue-to-rvalue conversion to
x
yields a constant expression that does not invoke any non-trivial functions" and - "
ex
is an element of the set of potential results of an expressione
" and either of the following holds:- "either the lvalue-to-rvalue conversion is applied to
e
" - "or
e
is a discarded-value expression"
- "either the lvalue-to-rvalue conversion is applied to
- "applying the lvalue-to-rvalue conversion to
applying lvalue-to-rvalue conversion to
x
yields a constant expression that doesn't invoke non-trivial functionsx
is an object and ex is one of the potential results of a larger expressione
, where that larger expression is either a discarded-value expression or an lvalue-to-rvalue conversion
和2来自cppreference http://en.cppreference.com/w/cpp/language/definition
一个变量<$ c除非任何成立,否则在潜在求值表达式
ex
中的$ c> x
关于两个规则的第一个答案是和,另一个是强>。哪一个是正确的?
请将规则分成多个步骤来说明此代码:
struct S {static const int x = 0; };
extern S s; //没有定义s
int i = s.x; //是s odr使用?是x odr使用?
// gcc 5.1.0 is ok
cppreference 是是错误的;从标准中的语言(无论哪个版本)都清楚,两个子句必须保持。
在您的示例中, s
不是常量表达式(C ++ 14:不满足出现在常量表达式中的要求),所以使用odr。
同时, x
也使用odr,因为虽然可能在适当的上下文中的常量表达式中使用 x
(例如作为 S
定义的数组) x
不是封闭表达式 sx
的潜在结果之一,这是唯一的封闭表达式丢弃值转换或左值到右值转换。
gcc可能没有 s的定义
或 x
,但没有要求实施诊断每个odr违例。
In N4296, 3.2 [basic.def.odr]p3:
A variable
x
whose name appears as a potentially-evaluated expressionex
is odr-used byex
unless applying the lvalue-to-rvalue conversion tox
yields a constant expression that does not invoke any non-trivial functions and, ifx
is an object,ex
is an element of the set of potential results of an expressione
, where either the lvalue-to-rvalue conversion is applied toe
, ore
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:
and 2 from cppreference http://en.cppreference.com/w/cpp/language/definition
a variable
x
in a potentially-evaluated expressionex
is odr-used unless any of the following is true:
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
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.
这篇关于关于类成员访问表达式的一个定义规则的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!