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
}
问题是:为什么gcc
和clang
(试过不同版本)在c ++ 98/03模式下正确编译代码但在编译时返回警告/错误在c ++ 11/14模式(-std=c++11
)?我试图找到C ++ 11工作草案PDF中的变化,但没有成功。
英特尔编译器16.0和VS2015编译器在两种情况下均未显示错误和警告。
答案 0 :(得分: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,其求值为零或类型为
std::nullptr_t
的prvalue。
在C ++ 14中它说:
空指针常量是整数文字(2.14.2),其值为零或prvalue类型为
std::nullptr_t
。
这是一个限制性更强的规则,更有意义。