说明了NULL,0,nullptr

说明了NULL,0,nullptr

问题描述:

考虑代码说明了NULL,0,nullptr

#include <iostream> 

void foo(int* p) 
{ 
    std::cout << "pointer" << '\n'; 
} 

void foo(int p) 
{ 
    std::cout << "value" << '\n'; 
}  

int main() 
{  
    foo(0); // value 
    foo(NULL); // error: call of overloaded ‘foo(NULL)’ is ambiguous foo(NULL); 

    return 0; 
} 

在这里我们可以看到一个问题,选择了空指针向右过载,这可以通过传递nullptr的功能foo的第二个电话来解决,但我的问题是关于不同的东西......

,因为我知道大多数实现定义NULL只是一个常量文字0像(#define NULL 0),因此预计在编译时有第二个呼叫是这样的 - foo(0)

但预处理器给出了一些奇怪的输出(运行g++ -std=c++11 -E main.cpp -o main后)

int main() 
{ 

foo(0); 

foo(
# 25 "main.cpp" 3 4 
    __null 
# 25 "main.cpp" 
     ); 

return 0; 
} 

什么是__null这里?

这是一个内置的int类型?

+3

看起来像那是特定实现(注意'__')。你正在使用哪种编译器? – user0042

+0

@ user0042我使用'g ++ 5.4.0' – ampawd

+0

https://gcc.gnu.org/onlinedocs/libstdc++/manual/support.html(最后一段)换句话说,'_null' magic关键字应该是准确地阻止你看到的内容(首先将'0'视为整数,然后将其转换为'nullptr')。 – Damon

__null是一个内置的编译器。 GCC使用它来提供更好的诊断。问题是,你真的要定义NULL

#define NULL ((void *) 0) 

- 就像在C.但与当前的C++,你就不能写

int *p = NULL; 

因为不像C,没有暗示从void *转换为其他指针类型。所以GCC实现了__null作为魔术空指针常量,它对于任何指针类型都是有效的,但它不是一个整数。因此,GCC可以发出警告

int a = NULL; 

否则将不可能。

基本上,__nullnullptr的早期版本,但它更保守,因为它只是一个扩展,而不是语言的改变。