为什么不调用 nullptr NULL?

Why not call nullptr NULL?

在 C++11 中,nullptr 关键字被添加为类型更安全的空指针常量,因为之前将 NULL 定义为 0 的常见定义存在一些问题。

为什么标准委员会选择不调用新的空指针常量 NULL,或者声明 NULL 应该 #defined 到 nullptr

如果没有真正参与标准委员会的讨论,很难确定,但我认为因为它会破坏一些使用 NULL 的代码,其含义为 nullptr不够兼容。打破旧代码从来都不是一个好主意。

Stephan T. Lavavej(C++ 标准委员会成员)解释说 talk (55:35):

虽然允许实现 #define NULL nullptr,但它会破坏很多用途,例如

int i = NULL;

而且显然有很多。所以他们不能强制改变。

nullptr指针类型,而NULL有整型倾向,有时在重载函数中需要明确您使用的是指针而不是整数 - 这就是 nullptr 派上用场的时候。

因此,要真正回答您的问题,NULLnullptr 有两个不同的目的,将一个重新定义为另一个可能会破坏现有代码库中的很多东西。

除此之外,从 Bjarne Stroustrup's website:

检查这个

Should I use NULL or 0?

In C++, the definition of NULL is 0, so there is only an aesthetic difference. I prefer to avoid macros, so I use 0. Another problem with NULL is that people sometimes mistakenly believe that it is different from 0 and/or not an integer. In pre-standard code, NULL was/is sometimes defined to something unsuitable and therefore had/has to be avoided. That's less common these days. If you have to name the null pointer, call it nullptr; that's what it's called in C++11. Then, "nullptr" will be a keyword.

NULL 不是类型安全的。由于历史原因,它被定义为 0 而没有转换,并且编译器将数字转换为指向此特殊零的指针的沉默警告。

对于瞬间,你可以这样做:

void* p = 0;

但如果没有隐式转换就不是这样:

void* p = 1234;

副作用是它可能被滥用为数字值,正如其他答案提到的那样。

nullptr 通过强制它是一个指针来改进它,你不能将它分配给一个整数。 由于行为已更改,因此创建了一个新名称以实现向后兼容性。

另请注意,nullptr 由编译器处理,其实际值不会暴露给用户(如 NULL 中的零)。在不影响程序员的代码逻辑的情况下,拥有依赖于体系结构的值要容易得多,比如 0xdeadbeef

引入nullptr是为了类型安全和清晰(可能是为了停止使用NULL初始化非指针类型)。

NULL(int型)没有改为nullptr(指针型),避免混淆,保证向后兼容。

因此,标准委员会的思路可能与从旧符号到新符号的平稳过渡有关,而不会引起歧义或破坏任何现有代码。

为什么标准委员会选择不调用新的空指针常量NULL

大概是因为新的空指针是一个关键字,而关键字不能是 #defined,所以调用它 NULL 会使包含任何 C 头文件的格式可能不正确。

或者声明NULL应该是#definednullptr

标准委员会确实允许 NULL#definednullptr,但并不要求它。

C++11 18.2 Types [support.types]/2: The macro NULL is an implementation-defined C++ null pointer constant in this International Standard.

C++11 4.10 Pointer conversions [conv.ptr]/1: A null pointer constant is an integral constant expression (5.19) prvalue of integer type that evaluates to zero or a prvalue of type std::nullptr_t.

向后兼容性在这里不是问题,任何假定 NULL 是整数 0 形式的使用都不符合标准。实现可能会选择不这样做,以纵容这种邪恶行为。

我将演示一个案例,其中将 nullptr 定义为不同类型的决定有助于防止错误。

考虑这些函数:

void foo(int);
void foo(char *);

int main()
{
    foo(NULL); // oops
}

在 C++98 中,上面的代码调用了 foo(int) 函数,因为 NULL 被替换为 0,这很可能不是您想要的。

但是如果你调用 foo(nullptr) 它会调用正确的 - foo(char*).