Grz*_*ski 6 c++ language-lawyer c++03
举个例子:
#include <iostream>
class A
{
public:
static const int numberOfWheels = 4;
};
// const int A::numberOfWheels;
int main()
{
std::cout << A::numberOfWheels << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
难道是正式未定义行为(UB),因为A::numberOfWheels是使用没有它的定义是什么?(另见这里).正如C++ 03所述:
如果在程序中使用该成员,并且名称空间范围定义不包含初始化程序,则该成员仍应在名称空间作用域中定义.
我发现在C++ 03 中使用的定义相当混乱,因为它指向可能被评估的表达式:
如果对象或非重载函数的名称出现在可能已评估的表达式中,则使用该函数.
从我的猜测来看,它排除了以下表达式:
sizeof(A::numberOfWheels) ;
typeid(A::numberOfWheels).name() ;
Run Code Online (Sandbox Code Playgroud)
但不一定是<<像上面那样重载运算符的表达式.
从这两个缺陷报告中可以看出它应该与使用的odr非常相似:缺陷报告48:未使用的静态成员的定义(强调我的未来):
最初,所有静态数据成员仍然必须在类外定义,无论它们是否被使用.
但是应该取消该限制,以便静态数据成员不需要在类外部定义,除非它们以与命名空间范围变量相同的方式以需要定义的方式使用.特别是,如果在类中初始化了整数/枚举const静态数据成员,并且从未采用其地址,则我们同意不需要命名空间范围定义.
这修改3.2p2如下:
表达式可能被评估,除非它出现在需要整数常量表达式的地方(见5.19 [expr.const]),是sizeof运算符的操作数(5.3.3 [expr.sizeof]),或者是typeid的操作数运算符和表达式不指定多态类类型的左值(5.2.8 [expr.typeid]).
3.2 basic.def.odr第2段中关于"可能评估"的措辞是不完整的.它不区分用作"整数常量表达式"的表达式和不用作"积分常量表达式"的表达式.它也不区分对象所在的用途和不用的对象.(可以在不实际说"地址"的情况下编写"地址"的合适定义.)
但是标准中的措辞没有被修改为包含缺陷报告中的陈述意图,并且不清楚为什么,只添加了需要整数常量表达式的例外.
更新
缺陷报告454:何时需要定义静态数据成员?最后以缺陷报告48中表达的意图同步标准的措辞,并说:
作为核心问题48的解决的结果,当前的C++标准与现有实践不同步并且与用户期望不同,只要涉及具有const整数或const枚举类型的静态数据成员的定义.基本上当前的实现只是在获取常量的地址时才需要定义.例:
Run Code Online (Sandbox Code Playgroud)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,section [basic.def.odr]意味着接近我们认为C++ 11中使用的odr使用的规则.随后通过缺陷报告712对C++ 11规则进行了更改,使C++ 11更接近C++ 14规则.
| 归档时间: |
|
| 查看次数: |
377 次 |
| 最近记录: |