为什么不调用nullptr NULL呢?

Why not call nullptr NULL?

本文关键字:NULL nullptr 调用 为什么不      更新时间:2023-10-16

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

为什么标准委员会选择不把新的空指针称为常量NULL,或者声明NULL应该是#define d到nullptr ?

Stephan T. Lavavej (c++标准委员会成员)在一次演讲(55:35)中解释说:

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

int i = NULL;

显然有很多这样的。所以他们不能强迫改变。

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

所以为了真正回答你的问题,NULLnullptr服务于两个不同的目的,将它们重新定义可能会破坏已经存在的代码库中的很多东西。

除此之外,查看Bjarne Stroustrup的网站:

我应该使用NULL还是0?

在c++中,NULL的定义是0,所以这只是审美上的的区别。我更喜欢避免使用宏,所以我使用0。另一个问题是NULL是指人们有时错误地认为它是不同的从0和/或非整数开始。在pre-standard代码中,NULL是/is有时被定义为不合适的事物,因此不得不存在避免的。现在这种情况不太常见了。如果你必须命名null指针,命名为nullptr;c++ 11就是这么叫的。然后,"nullptr"将是一个关键字。

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

现在,你可以这样做:

void* p = 0;

,但没有隐式强制转换的

void* p = 1234;

的副作用是它可以被滥用为数值,正如其他答案所提到的。

nullptr通过强制它是一个指针来改进这一点,你不能把它赋值给一个整数。由于行为发生了变化,为了向后兼容,将创建一个新名称。

还要注意,nullptr是由编译器处理的,它的实际值不暴露给用户(如NULL为零)。在不影响程序员代码逻辑的情况下,拥有与体系结构相关的值要容易得多,比如0xdeadbeef

如果没有实际参加标准委员会的讨论,很难确定,但我认为,因为它会破坏一些使用NULL的代码,而nullptr不能充分兼容。打破旧的代码从来都不是一个好主意。

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

可能是因为新的空指针是一个关键字,而关键字不能是#defined,所以称它为NULL会使包含任何C头文件可能是错误的。

或者声明NULL应该是#definednullptr ?

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

c++ 11 18.2类型(support.types)/2 :宏NULL是本国际标准中实现定义的c++空指针常量。

4.10指针转换[convr .ptr]/1:空指针常量是一个整型常量表达式(5.19),值为0的整型右值或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*)

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

NULL (int类型)不更改为nullptr(指针类型),以避免混淆,并确保向后兼容。

因此,标准委员会的思路可能与从旧符号到新符号的平稳过渡有关,而不会造成歧义或中断任何已经存在的代码。