2016-05-31 63 views
12

我最近偶然发现了一些奇怪的事情:将一个布尔值转换为指针可在Visual Studio 2013和2015中工作,但不能在GCC和Clang(3.5中尝试)中使用。将bool(false)转换为C++中的合法指针吗?

#include <iostream> 

using namespace std; 

void foo(int *ptr) 
{ 
    std::cout << "foo"; 
} 

int main() 
{ 
    foo(false); 
} 

错误GCC

main.cpp: In function 'int main()': 
    main.cpp:13:13: error: cannot convert 'bool' to 'int*' for argument '1' to 'void foo(int*)' 
    foo(false); 
      ^

我的猜测是虚假转换为0这相当于NULL。将呼叫替换为foofoo(true)会导致编译失败,每个编译器都会失败。

所以我的问题是:这段代码应该编译?我没有看到将false转换为指针的好处,但在我看来,这只会是滥用/重构等错误的原因。

+3

相关:[防止虚假到指针无声铸(http://stackoverflow.com/q/21025179/3425536) – emlai

+1

@DieterLücking我不认为这是重复的,OP想知道的是它允许和哪个编译器(gcc,clang,vc)是正确的。 – songyuanyao

+0

该死的,我没有找到它,并没有找到任何相关的东西。尽管它有效吗?如果是这样,为什么clang在编译时出错?它是一个编译器错误还是它没有在标准中真正定义? – Uflex

回答

6

从C++ 11开始,这不应该被接受。

参见Pointer conversions(重点煤矿):

空指针常数(见NULL),可以被转换为任何指针类型,并且结果是该类型的空指针值。这种转换(称为空指针转换)被允许转换为cv合格类型作为单个转换,也就是说,它的不被视为数字转换和限定转换的组合。因为C++ 11一个null pointer constant

注意可能字面具有值零(或类型std::nullptr_t的prvalue)的整数,而false不是,这是一个boolean literal

并且直到C++ 11空指针常量被定义为整数类型的整数常量表达式rvalue值为零,而false没问题。 (GCC将给予它一个警告。)

从标准,$4.10/1 Pointer conversions [conv.ptr](重点煤矿)

空指针常数是的整数字面(2.13.2)与零值或prvalue类型std :: nullptr_t。

一个空指针恒定的指针CV-合格 型的转化是单个转换,而不是一个指针 转换后跟一个资格转换(4.4)的序列。

+3

请注意,这仅适用于包含[问题903](http://open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#903)的C++ 11。由于C++ 11最初发布时,空指针常量是“一个整型常量表达式......”,其中“false”是。我最近在[答案](http://stackoverflow.com/a/372​​14551/1782465)中解决了这个问题。 – Angew

+0

@Angew感谢您指出。 – songyuanyao