C++11 向后兼容性(空整数常量到指针的转换)

C++11 backwards compatibility (conversion of null integer constant to pointer)

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

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

float* foo()
{
    int v = 0;
    return v;    // Error
}

但是下面的代码是正确的:

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

问题是:为什么gccclang(试过不同的版本)在c++98/03模式下编译代码正确但是return warning/error 在 c++11/14 模式下编译时 (-std=c++11)?我试图找到 C++11 工作草案 PDF 中的更改,但没有成功。

Intel 编译器 16.0 和 VS2015 编译器在这两种情况下均未显示任何错误和警告。

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

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

A null pointer constant is an integral constant expression (5.19) rvalue of integer type that evaluates to zero.

这允许各种表达式,只要它们是常量且计算结果为零即可。枚举、false(5 - 5) 等等......这曾经在 C++03 代码中引起很多问题。

在 C++11 中它说:

A null pointer constant is an integral constant expression (5.19) prvalue of integer type that evaluates to zero or a prvalue of type std::nullptr_t.

在 C++14 中它说:

A null pointer constant is an integer literal (2.14.2) with value zero or a prvalue of type std::nullptr_t.

这是一个更严格的规则,也更有意义。