【问题标题】:Does "potentially-evaluated" means the same as "odr-used" in C++03?“潜在评估”的含义与 C++03 中的“使用过的”相同吗?
【发布时间】:2015-07-22 14:20:25
【问题描述】:

举个例子:

#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 在没有定义的情况下使用? (另见here)。正如 C++03 所说:

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

我发现 C++03 中 used 的定义相当混乱,因为它指向 potentially-evaluated 表达式:

如果对象或非重载函数的名称出现在 潜在评估的表达式。

根据我的猜测,它不包括以下表达式:

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

但不一定是像上面那样重载&lt;&lt; 运算符的表达式。

【问题讨论】:

  • 已更新,缺陷报告 454 澄清了这一点,并在 2006 年更新了标准中的语言。

标签: c++ language-lawyer c++03


【解决方案1】:

从这两个缺陷报告看来,它应该与 odr-used:defect report 48: Definitions of unused static members 非常相似的意图是(强调我的未来):

最初,所有静态数据成员仍然必须在外部定义 类,无论它们是否被使用。

但是这个限制应该被取消,以便静态数据 成员不需要在类之外定义,除非它们被用于 一种需要定义它们的方式,方式与 命名空间范围的变量。特别是,如果一个整数/枚举 const 静态数据成员在类中初始化,其地址为 从未采用,我们同意没有命名空间范围定义 需要。

这个修改3.2p2如下:

一个表达式可能会被计算,除非 它出现在 需要整数常量表达式(参见 5.19 [expr.const] ), 是 sizeof 运算符 (5.3.3 [expr.sizeof] ) 的操作数,或者是 typeid 运算符的操作数和表达式不 指定多态类类型的左值 (5.2.8 [expr.typeid] )。

defect report 82: Definition of "using" a constant expression :

3.2 basic.def.odr 第 2 段中关于“可能 评估”是不完整的。它不区分表达式 用作“整数常量表达式”和那些 不是;它也不区分对象寻址的用途 被采取和那些不是。 (一个合适的定义 “取地址”可以写成不实际说“地址”。)

但是标准中的措辞没有被修改以包含两个缺陷报告中声明的意图,也不清楚为什么,只添加了需要整数常量表达式的例外情况。

更新

defect report 454: When is a definition of a static data member required? 最终将标准的措辞与缺陷报告 48 中表达的意图同步,它说:

由于核心问题 48 的解决,当前的 C++ 标准与现有实践和用户不同步 对具有 const 的静态数据成员的定义的期望 涉及整数或 const 枚举类型。基本上是什么 当前的实现只需要一个定义,如果 获取常量的地址。示例:

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 段。

因此,对于 C++03 部分,[basic.def.odr] 旨在涵盖接近我们认为 C++11 中使用 odr 的规则。随后通过defect report 712 对 C++11 规则进行了更改,使 C++11 更接近 C++14 规则。

【讨论】:

    猜你喜欢
    • 2013-12-01
    • 2018-01-05
    • 1970-01-01
    • 2018-10-22
    • 2011-08-08
    • 2020-04-16
    • 2014-09-07
    • 1970-01-01
    • 2021-12-19
    相关资源
    最近更新 更多