对NULL,0,nullptr的解释

时间:2017-11-11 14:44:42

标签: c++ c++11 null g++ null-pointer

考虑代码

#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类型吗?

1 个答案:

答案 0 :(得分:3)

__null是内置的编译器。 GCC使用它来提供更好的诊断。问题是你真的想将NULL定义为

#define NULL ((void *) 0)

- 就像在C中一样。但是使用当前的C ++,你将无法编写

int *p = NULL;

因为与C不同,没有从void *到其他指针类型的隐含转换。因此GCC将__null实现为一个魔术空指针常量,它对任何指针类型都有效,但不是整数。因此,海湾合作委员会可以发出

的警告
int a = NULL;

否则这是不可能的。

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