在C ++ 11中,nullptr
关键字被添加为类型更安全的空指针常量,因为先前的NULL
as常见定义为0。
标准委员会为什么选择不调用新的空指针常量NULL
,或者声明不NULL
应该将其声明为#define
d nullptr
?
在C ++ 11中,nullptr
关键字被添加为类型更安全的空指针常量,因为先前的NULL
as常见定义为0。
标准委员会为什么选择不调用新的空指针常量NULL
,或者声明不NULL
应该将其声明为#define
d nullptr
?
Answers:
C ++标准委员会成员Stephan T. Lavavej解释说,在一次演讲中(55:35):
虽然允许一个实现#define NULL nullptr
,但它会破坏很多用途,例如
int i = NULL;
显然有很多。因此,他们无法强制进行更改。
int
,我偶尔遇到一些代码,其中有人使用来“终止字符串” str[end_pos] = NULL;
。
int i = NULL;
是并且一直是邪恶的。您为什么要这样做?
str[end_pos] = NULL
或str[end_pos] = 0
,或使用13
代替\r
,例如-都是常用的。类型在C中没什么大不了的。另一个例子是被滥用的情况long
,特别是当与常规将指针强制转换为int
or的方式结合使用时long
。“发明”的人int i = NULL
可能以为这是一种很明显的说法,即“现在将int i
其初始化为默认值”。这是可悲的,但有很多类似的做法C.
NULL
定义为技术上((void*) 0)
已经int i = NULL;
非法。
nullptr
是指针类型的,虽然NULL
倾向于为整数,有时在重载函数中使用,但需要清楚的是您使用的是指针而不是整数-这很nullptr
方便。
因此,要真正回答您的问题NULL
并nullptr
达到两个不同的目的,然后将它们重新定义,可能会破坏已经存在的代码库中的许多内容。
除此之外,还可以从Bjarne Stroustrup的网站上进行检查:
我应该使用NULL还是0?
在C ++中,NULL的定义为0,因此仅存在美学差异。我更喜欢避免使用宏,因此我使用0。NULL的另一个问题是,人们有时会错误地认为它不同于0和/或不是整数。在标准前代码中,有时将NULL定义为不合适的值,因此必须避免。这些天来这种情况不太常见。如果必须命名空指针,则将其命名为nullptr;这就是C ++ 11中的名称。然后,“ nullptr”将成为关键字。
NULL
不是类型安全的。出于历史原因,它被定义为0而没有强制转换,并且编译器将警告将强制转换为指向该特殊零的指针的数字。
您可以立即执行以下操作:
void* p = 0;
但是没有隐式强制转换则不是这样:
void* p = 1234;
副作用是它可能被滥用为数字值,如其他答案所述。
nullptr
通过强制它是一个指针来改进它,您不能将其分配给整数。由于行为已更改,因此将创建一个新名称以实现向后兼容。
另请注意,nullptr
由编译器处理,它的实际值不向用户公开(如为,则为零NULL
)。例如,拥有依赖于体系结构的值要容易得多0xdeadbeef
,而又不影响程序员的代码逻辑。
NULL
大概是因为新的空指针是一个关键字,而关键字不能是#defined
,所以调用它NULL
将使任何C头的包含都可能格式错误。
NULL
应#defined
为nullptr
?标准委员会确实允许NULL
使用#defined
to 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
都不符合标准的用法。实现者可能选择不这样做来纵容这种邪恶的行为。
我将演示一个案例,将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一样。
nullptr
引入的目的是为了确保类型安全和清楚(可能使用停止非指针类型的初始化NULL
)。
的NULL
(整型)不改变到nullptr
(指针型),以避免混淆,并保证向后兼容性。
因此,标准委员会的思路可能与从旧符号到新符号的平滑过渡而不会引起歧义或制止任何已经存在的代码。
types
,这就是为什么我在澄清之后将它们明确地放在后面。当然,创建指针NULL
不会引起混淆,但是公认的答案为您提供了一个示例,说明为什么NULL的类型未更改为nullptr
。