空指针常量初始化:哪种行为是正确的?

Bri*_*ian 6 c++ pointers language-lawyer c++11

int main() {
    const int x = 0;
    int* y = x;   // line 3
    int* z = x+x; // line 4
}
Run Code Online (Sandbox Code Playgroud)

标准(C++11§4.10/ 1)

空指针常数是整数表达式(5.19),用于评估至零或类型的prvalue整数类型的prvalue std::nullptr_t.空指针常量可以转换为指针类型; ...

有四种可能性:

  1. 第4行没问题,但第3行没有.这是因为x并且x+x都是常量表达式,其值为0,但只是x+x一个prvalue.似乎gcc采用了这种解释(现场演示)

  2. 第3行和第4行都可以.虽然x是左值,但是应用了左值到右值的转换,使得prvalue常量表达式等于0.我的系统上的clang(clang-3.0)接受第3行和第4行.

  3. 第3行和第4行都不正常.clang-3.4两行错误(现场演示).

  4. 第3行没问题,但第4行没有.(包括为了完整性,即使我尝试的编译器没有表现出这种行为.)

谁是对的?是否取决于我们正在考虑的标准版本?

ric*_*ici 10

由于DR 903,标准中的措辞发生了变化.新的措辞是

空指针常量是一个整数文字(2.14.2),其值为零或prvalue类型std::nullptr_t.

问题903涉及一个奇怪的角落情况,在模板参数是(可能是0)整数常量的某些情况下,不可能产生"正确的"重载分辨率.

显然考虑了一些可能的决议,但是

CWG中有一个强烈的共识,即只有文字0应该被认为是空指针常量,而不是当前指定的任何零值常量表达式.

所以,是的,这取决于编译器是否已经实现了DR 903的分辨率.