“潜在评估”表示与“odr使用的”相同。在C ++ 03? [英] Does "potentially-evaluated" means the same as "odr-used" in C++03?

查看:203
本文介绍了“潜在评估”表示与“odr使用的”相同。在C ++ 03?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出一个示例:

#include <iostream>

class A
{
public:
    static const int numberOfWheels = 4;
};

// const int A::numberOfWheels;

int main()
{
    std::cout << A::numberOfWheels << std::endl;
}

是正式未定义的行为( UB ),因为 A :: numberOfWheels 是否使用而没有定义? (另见此处)。由于C ++ 03声明:

Is it formally undefined behavior(UB) since A::numberOfWheels is used without its definition? (see also here). As C++03 states:


如果在程序中使用
,成员仍然在命名空间范围内定义并且命名空间范围定义不应包含
初始化程序。

The member shall still be defined in a namespace scope if it is used in the program and the namespace scope definition shall not contain an initializer.

我发现的定义在C ++ 03中是非常混乱的,因为它指向潜在评估的表达式:

I found that definition of used in C++03 is rather confusing, as it points to potentially-evaluated expression:


An object or non-overloaded function is used if its name appears in a potentially-evaluated expression.



如果
可能计算的表达式中出现

从我的野生猜测它排除了表达式如:

From my wild guess it excludes expressions such as:

sizeof(A::numberOfWheels) ;
typeid(A::numberOfWheels).name() ;

,但不一定是重载的表达式<< 运算符。

but not necessarily an expression with overloaded << operator like above.

推荐答案

从这两个缺陷报告看来,它的意图应该非常类似于odr-used:缺陷报告48:未使用的静态成员的定义强调我的未来):

From these two defect reports it seems that was the intent that it should be very similar to odr-used: defect report 48: Definitions of unused static members which says (emphasis mine going forward):


最初,所有静态数据成员在
之外定义类是否被使用。

Originally, all static data members still had to be defined outside the class whether they were used or not.

但是这个限制应该解除,以便静态数据
成员需要不是在类外部定义,除非它们以
a方式使用,这需要它们的定义,方式与
命名空间范围变量相同。特别是,如果在类中初始化了一个积分/枚举const
静态数据成员,并且它的地址是
从不采用,我们同意没有命名空间范围定义是

But that restriction was supposed to be lifted so that static data members need not be defined outside the class unless they are used in a manner which requires their definition, in the same manner as namespace-scope variables. In particular, if an integral/enum const static data member is initialized within the class, and its address is never taken, we agreed that no namespace-scope definition was required.

此修改 3.2p2 如下: p>

this modified 3.2p2 as follows:


除非出现需要
整数常量表达式的位置,否则可能会评估表达式(请参阅5.19 [expr.const] )

是sizeof运算符的操作数(5.3.3 [expr.sizeof]),或者是
是typeid运算符的操作数,表达式不是

An expression is potentially evaluated unless it appears where an integral constant expression is required (see 5.19 [expr.const] ), is the operand of the sizeof operator (5.3.3 [expr.sizeof] ), or is the operand of the typeid operator and the expression does not designate an lvalue of polymorphic class type (5.2.8 [expr.typeid] ).

缺陷报告82:定义使用常量表达式


3.2 basic.def.odr第2段中关于潜在
已评估的措辞不完整。它不区分用作整数常数表达式的表达式
和不是
的表达式;也不区分对象地址
的使用和不使用对象地址
的使用。 (
address taken的合适定义可以写成,而不用说地址。)

The wording in 3.2 basic.def.odr paragraph 2 about "potentially evaluated" is incomplete. It does not distinguish between expressions which are used as "integral constant expressions" and those which are not; nor does it distinguish between uses in which an objects address is taken and those in which it is not. (A suitable definition of "address taken" could be written without actually saying "address".)

在标准中没有被修改以包含在缺陷报告中的所述意图,并且不清楚为什么,仅仅在需要整数常数表达式的地方添加了异常。

But the wording in the standard was not modified to encompassed the stated intent in either defect report and it is not clear why, only added the exception for where a integral constant expression is required.

更新

缺陷报告454:何时需要静态数据成员的定义? 最终将标准的措辞与缺陷报告48中表达的意图同步,并且表示:

defect report 454: When is a definition of a static data member required? finally synced up the wording of the standard with the intent expressed in defect report 48 and it says:


核心问题48的解决方案,目前的C ++
标准与现有实践不同步,并且与用户
期望一样,对于具有const
整数或const枚举类型的静态数据成员的定义关心。基本上,
当前的实现是要求一个定义,只有当
地址的常量。示例:

As a result of the resolution of core issue 48, the current C++ standard is not in sync with existing practice and with user expectations as far as definitions of static data members having const integral or const enumeration type are concerned. Basically what current implementations do is to require a definition only if the address of the constant is taken. Example:

void f() {

  std::string s;
  ... 

  // current implementations don't require a definition
  if (s.find('a', 3) == std::string::npos) {
   ...
  }

虽然,上面需要一个定义
的npos,因为表达式std :: string :: npos可能
求值。我认为这个问题很容易解决与简单
更改9.4.2 class.static.data第4段,9.4.2
class.static.data第5段和3.2 basic.def.odr段落3 。

To the letter of the standard, though, the above requires a definition of npos, since the expression std::string::npos is potentially evaluated. I think this problem would be easily solved with simple changes to 9.4.2 class.static.data paragraph 4, 9.4.2 class.static.data paragraph 5 and 3.2 basic.def.odr paragraph 3.

所以对于C ++ 03部分 [basic.def.odr] 我们认为从C ++ 11的odr使用的规则。通过缺陷报告712 ,使C ++ 11更接近C ++ 14规则。

So for C++03 section [basic.def.odr] was meant to cover close to what we consider the odr-used rules from C++11. There were subsequent changes to the C++11 rules via defect report 712 which bring C++11 closer to the C++14 rules.

这篇关于“潜在评估”表示与“odr使用的”相同。在C ++ 03?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆