考虑代码

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

最佳答案

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

#define NULL ((void *) 0)

—就像在C中一样。但是使用当前的C++,您将无法编写
int *p = NULL;

因为与C不同,它不存在从void *到其他指针类型的隐式转换。因此,GCC将__null实现为魔术空指针常量,该常量对任何指针类型均有效,但不是整数。因此,GCC可以针对
int a = NULL;

否则是不可能的。

从本质上讲,__nullnullptr的早期版本,但由于它只是扩展而不是语言更改,因此更为保守。

关于c++ - NULL,0,nullptr的解释,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47239124/

10-13 04:36