为什么不将nullptr称为NULL?


68

在C ++ 11中,nullptr关键字被添加为类型更安全的空指针常量,因为先前的NULLas常见定义为0。

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




10
这些都不反映标准措词背后的原因。
Baum mit Augen

Answers:


71

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

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

int i = NULL;

显然有很多。因此,他们无法强制进行更改。


3
我曾希望他们至少不赞成这样做,以便将来可以将NULL定义为nullptr ...(或将nullptr称为NULL,并且nullptr_t可以弃用转换为int)
user253751,2015年

4
对于类似的示例int,我偶尔遇到一些代码,其中有人使用来“终止字符串” str[end_pos] = NULL;
稻田

11
int i = NULL;是并且一直是邪恶的。您为什么要这样做?
TNA

9
@TNA好吧,C在这种情况下有点邪恶。就像使用str[end_pos] = NULLstr[end_pos] = 0,或使用13代替\r,例如-都是常用的。类型在C中没什么大不了的。另一个例子是被滥用的情况long,特别是当与常规将指针强制转换为intor的方式结合使用时long。“发明”的人int i = NULL可能以为这是一种很明显的说法,即“现在将int i其初始化为默认值”。这是可悲的,但有很多类似的做法C.
Luaan

5
@Luaan C允许NULL定义为技术上((void*) 0)已经int i = NULL;非法。
jamesdlin

43

nullptr指针类型的,虽然NULL倾向于为整数,有时在重载函数中使用,但需要清楚的是您使用的是指针而不是整数-这很nullptr方便。

因此,要真正回答您的问题NULLnullptr达到两个不同的目的,然后将它们重新定义,可能会破坏已经存在的代码库中的许多内容。

除此之外,还可以从Bjarne Stroustrup的网站上进行检查:

我应该使用NULL还是0?

在C ++中,NULL的定义为0,因此仅存在美学差异。我更喜欢避免使用宏,因此我使用0。NULL的另一个问题是,人们有时会错误地认为它不同于0和/或不是整数。在标准前代码中,有时将NULL定义为不合适的值,因此必须避免。这些天来这种情况不太常见。如果必须命名空指针,则将其命名为nullptr;这就是C ++ 11中的名称。然后,“ nullptr”将成为关键字。


但这就是问题-为什么不将NULL更改为nullptr是什么?
user253751's

2
@immibis,因为您不能将int变量(仅作为示例)初始化为指针类型NULL(即nullptr),这将是一个很大的问题。
Kiloreux

5
从技术上讲,nullptr不是指针类型,而是type nullptr_t

@Hurkyl,确保我只是在试图阐明概念,也许您应该编辑答案以包括该内容。
Kiloreux

8

在没有参加标准委员会的讨论的情况下,很难肯定地说,但我想是因为这会破坏某些NULLnullptr不充分兼容的意义上使用的代码。破坏旧代码绝不是一个好主意。


8

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

您可以立即执行以下操作:

void* p = 0;

但是没有隐式强制转换则不是这样:

void* p = 1234;

副作用是它可能被滥用为数字值,如其他答案所述。

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

另请注意,nullptr由编译器处理,它的实际值不向用户公开(如为,则为零NULL)。例如,拥有依赖于体系结构的值要容易得多0xdeadbeef,而又不影响程序员的代码逻辑。


2
现在我饿了一些死牛肉。
dub stylee

4
@dubstylee 0xfeedface 0xdeadbeef?0xfeedface 0xcafef00d!(我们以前有一个带有4位十六进制显示的系统,该小组中的每个人都几乎知道每个仅包含字符a,b,c,d,e,f,i和o的4个字母的单词,并且使用了他们互相交谈。)
Erik Johnson

2

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

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

或声明NULL#definednullptr

标准委员会确实允许NULL使用#definedto nullptr,但是并不需要。

C ++ 11 18.2类型[support.types] / 2:宏NULL是此国际标准中实现定义的C ++空指针常量。

C ++ 11 4.10指针转换[conv.ptr] / 1空指针常量是整数类型的整数常量表达式(5.19)prvalue,其结果为零或type的prvalue std::nullptr_t

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


2

我将演示一个案例,将nullptr定义为其他类型有助于防止bug。

考虑以下功能:

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

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

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

但是,如果您调用foo(nullptr),它将调用正确的一个-foo(char *)


就像foo(NULL)他们将NULL更改为nullptr一样。
user253751

@immibis是的,但是他们不想破坏现有代码,这是我同意的。
米纳斯米纳2015年

1

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

NULL(整型)不改变到nullptr(指针型),以避免混淆,并保证向后兼容性。

因此,标准委员会的思路可能与从旧符号到新符号的平滑过渡而不会引起歧义或制止任何已经存在的代码。


将NULL用作指针类型会引起混乱吗?如果有的话,我想这会避免混乱。
user253751

@immibis它说:“ NULL(int type)不会更改为nullptr(pointer type)”,以避免混淆,它在问题的上下文中。混乱涉及types,这就是为什么我在澄清之后将它们明确地放在后面。当然,创建指针NULL不会引起混淆,但是公认的答案为您提供了一个示例,说明为什么NULL的类型未更改为nullptr
Ziezi
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.