一条关于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:
- 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 expression e
" and either of the following holds:
- "either the lvalue-to-rvalue conversion is applied to
e
"
- "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 在没有定义 s
或 x
的情况下可能没问题,但不要求实现诊断每个 odr 违规。
在 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.
这一段怎么解释?我找到了两个解释。
1 从这里“
Let's split this into steps: The occurrence of a variable `x` in an expression `ex` constitutes an odr-use unless:
- 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"
和 2 个来自 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:
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 expressione
, 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 在没有定义 s
或 x
的情况下可能没问题,但不要求实现诊断每个 odr 违规。