为什么不调用 nullptr NULL?
Why not call nullptr NULL?
在 C++11 中,nullptr
关键字被添加为类型更安全的空指针常量,因为之前将 NULL
定义为 0 的常见定义存在一些问题。
为什么标准委员会选择不调用新的空指针常量 NULL
,或者声明 NULL
应该 #define
d 到 nullptr
?
如果没有真正参与标准委员会的讨论,很难确定,但我认为因为它会破坏一些使用 NULL
的代码,其含义为 nullptr
不够兼容。打破旧代码从来都不是一个好主意。
Stephan T. Lavavej(C++ 标准委员会成员)解释说 talk (55:35):
虽然允许实现 #define NULL nullptr
,但它会破坏很多用途,例如
int i = NULL;
而且显然有很多。所以他们不能强制改变。
nullptr
是指针类型,而NULL
有整型倾向,有时在重载函数中需要明确您使用的是指针而不是整数 - 这就是 nullptr
派上用场的时候。
因此,要真正回答您的问题,NULL
和 nullptr
有两个不同的目的,将一个重新定义为另一个可能会破坏现有代码库中的很多东西。
除此之外,从 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
应该是#defined
到nullptr
?
标准委员会确实允许 NULL
为 #defined
到 nullptr
,但并不要求它。
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*).
在 C++11 中,nullptr
关键字被添加为类型更安全的空指针常量,因为之前将 NULL
定义为 0 的常见定义存在一些问题。
为什么标准委员会选择不调用新的空指针常量 NULL
,或者声明 NULL
应该 #define
d 到 nullptr
?
如果没有真正参与标准委员会的讨论,很难确定,但我认为因为它会破坏一些使用 NULL
的代码,其含义为 nullptr
不够兼容。打破旧代码从来都不是一个好主意。
Stephan T. Lavavej(C++ 标准委员会成员)解释说 talk (55:35):
虽然允许实现 #define NULL nullptr
,但它会破坏很多用途,例如
int i = NULL;
而且显然有很多。所以他们不能强制改变。
nullptr
是指针类型,而NULL
有整型倾向,有时在重载函数中需要明确您使用的是指针而不是整数 - 这就是 nullptr
派上用场的时候。
因此,要真正回答您的问题,NULL
和 nullptr
有两个不同的目的,将一个重新定义为另一个可能会破坏现有代码库中的很多东西。
除此之外,从 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
应该是#defined
到nullptr
?
标准委员会确实允许 NULL
为 #defined
到 nullptr
,但并不要求它。
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*).