C++ 11向后兼容性(将null整数常量转换为指针)

And*_*nov 10 c++ g++ language-lawyer c++11

C++标准允许将零整数常量隐式转换为任何类型的指针.

以下代码无效,因为v此处的值不是常量:

float* foo()
{
    int v = 0;
    return v;    // Error
}
Run Code Online (Sandbox Code Playgroud)

但是以下代码是正确的:

float* foo()
{
    const int v = 0;
    return v;    // Ok in C++98 mode, error in C++11 mode
}
Run Code Online (Sandbox Code Playgroud)

问题是:为什么gccclang(试过不同的版本)在c ++ 98/03模式下正确编译代码但在c ++ 11/14模式下编译时返回警告/错误(-std=c++11)?我试图找到C++ 11工作草案PDF中的变化,但没有成功.

英特尔编译器16.0和VS2015编译器在两种情况下都没有显示错误和警告.

Jon*_*ely 11

GCC和Clang的行为不同,-std=c++11因为C++ 11更改了空指针常量的定义,然后C++ 14再次更改它,请参阅Core DR 903,它改变了C++ 14中的规则,以便只有文字为空指针常量.

在C++ 03 4.10 [conv.ptr]中说:

空指针常量是整数类型的整数常量表达式(5.19)rvalue,其值为零.

这允许各种表达式,只要它们是常量并且评估为零.枚举,false,(5 - 5)等等,等等......这曾经引起很多的C++代码03的问题.

在C++ 11中它说:

空指针常量是整数类型的整数常量表达式(5.19)prvalue,其计算结果为零或类型的prvalue std::nullptr_t.

在C++ 14中它说:

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

这是一个更加严格的规则,更有意义.