说明了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类型?
答
__null
是一个内置的编译器。 GCC使用它来提供更好的诊断。问题是,你真的要定义NULL
为
#define NULL ((void *) 0)
- 就像在C.但与当前的C++,你就不能写
int *p = NULL;
因为不像C,没有暗示从void *
转换为其他指针类型。所以GCC实现了__null
作为魔术空指针常量,它对于任何指针类型都是有效的,但它不是一个整数。因此,GCC可以发出警告
int a = NULL;
否则将不可能。
基本上,__null
是nullptr
的早期版本,但它更保守,因为它只是一个扩展,而不是语言的改变。
看起来像那是特定实现(注意'__')。你正在使用哪种编译器? – user0042
@ user0042我使用'g ++ 5.4.0' – ampawd
https://gcc.gnu.org/onlinedocs/libstdc++/manual/support.html(最后一段)换句话说,'_null' magic关键字应该是准确地阻止你看到的内容(首先将'0'视为整数,然后将其转换为'nullptr')。 – Damon