为什么不调用nullptr NULL?

use*_*751 67 c++ language-design c++11

在C++ 11中,nullptr关键字被添加为更安全的类型指针常量,因为先前的通用定义NULL为0有一些问题.

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

Bau*_*gen 70

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

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

int i = NULL;
Run Code Online (Sandbox Code Playgroud)

显然有很多这些.所以他们无法强迫改变.

  • `int i = NULL;`是,并且一直是邪恶的.你为什么要这样做? (10认同)
  • @TNA嗯,C就是这样的邪恶.这就像使用`str [end_pos] = NULL`或`str [end_pos] = 0`,或者使用`13`而不是`\ r``一样 - 都是常用的.类型在C中并不是什么大问题...另一个例子是被误用的`long`,特别是当与指针常规地转换为`int`或`long`的方式结合时."发明"`int i = NULL`的人可能认为这是一种非常明显的说法,"现在`int i`初始化为默认值".这很难过,但C中有很多类似的做法. (9认同)
  • @Luaan C允许将`NULL`定义为`((void*)0)`并且已经使`int i = NULL;`技术上非法. (5认同)
  • 对于类似于`int`的例子,我偶尔会遇到一些代码,其中有人用`str [end_pos] = NULL;`来"终止"他们的字符串. (4认同)
  • 我曾希望他们至少*弃用*这样,以便将来可以将NULL定义为nullptr ...(或者,所以nullptr可以被称为NULL,而nullptr_t可能会被弃用转换为int) (3认同)
  • @Luaan 不要把 C 带进来。`str[end_pos] = NULL` 和 `int i = NULL` *仅*保证在 C++ 中有效。(C 实际上并没有指定 `NULL` 的定义,但它在任何理智的实现中都不是一个 int;它只是在 C++ 中需要 `NULL` 是一个整数。) (2认同)
  • @Leushenko “`int i = NULL` [is] 仅保证在 C++ 中有效...`NULL` [is] 在任何正常的实现中都不是 int”——GCC 5.1 不会抱怨 `int i = NULL ` 即使使用 `-Wall -Wextra -pedantic -ansi`。但你是对的,“NULL”被定义为“((void *)0)”。尽管如此,显然还是允许将空指针自动转换为 0 整数(甚至 [在 CERT 安全编码标准中提出](https://www.securecoding.cert.org/confluence/display/c/INT36- C.+Converting+a+pointer+to+integer+or+integer+to+pointer)作为明确允许的事情)。 (2认同)
  • 我认为打破这种恶劣的行为是可以的。不应该允许开发人员仅仅因为它运行而编写愚蠢的代码;) (2认同)
  • @BenLeggiero 那么 C++11 最终会像 D-它比旧的 C++ 更好,但没有人使用它。有些公司的日常业务需要依赖 30 年前的代码库,你知道吗? (2认同)
  • 因此,C++ 创建了 nullptr 来解决将 NULL 定义为 0 而不是像 C 那样的 (void *)0 所带来的问题,从而不必要地进一步增加了 C++ 的复杂性。 (2认同)

Kil*_*eux 41

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

因此,要真正回答您的问题,NULL并nullptr为不同的目的服务并重新定义彼此可能会在已经存在的代码库中打破很多东西.

除此之外,

从Bjarne Stroustrup的网站上查看

我应该使用NULL还是0?

在C++中,NULL的定义是0,因此只有美学差异.我更喜欢避免宏,所以我使用0. NULL的另一个问题是人们有时会错误地认为它与0不同和/或不是整数.在预标准代码中,NULL有时被定义为不适合的东西,因此必须/必须避免.这些日子不太常见.如果必须命名空指针,则将其命名为nullptr; 这就是它在C++ 11中所称的内容.然后,"nullptr"将是一个关键字.

  • 从技术上讲,`nullptr`不是指针类型,而是类型`nullptr_t`. (5认同)
  • @immibis因为你不能初始化int变量(只是一个例子)到指针类型NULL(这是nullptr),这将是一个很大的问题. (2认同)

Mat*_*son 8

如果没有真正参与标准委员会的讨论,很难肯定地说,但我认为,因为它会打破一些代码,这些代码使用NULL的意义nullptr不完全兼容.打破旧代码永远不是一个好主意.


Non*_*upt 8

NULL不是类型安全的.由于历史原因,它在没有强制转换的情况下被定义为0,并且编译器将对于此特殊零点上的转换数量的警告静音.

对于即时,你可以这样做:

void* p = 0;
Run Code Online (Sandbox Code Playgroud)

但是如果没有隐式转换,请注意

void* p = 1234;
Run Code Online (Sandbox Code Playgroud)

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

nullptr通过强制执行它是一个指针来改进它,你不能将它赋给一个整数.由于行为已更改,因此会为向后兼容性创建新名称.

另请注意,nullptr由编译器处理,其实际值不向用户公开(如果为零则为零NULL).例如0xdeadbeef,在不影响程序员的代码逻辑的情况下,拥有与体系结构相关的值要容易得多.

  • @dubstylee 0xfeedface 0xdeadbeef?0xfeedface 0xcafef00d!(我们曾经有一个带有4位十六进制显示的系统,该组中的每个人都知道几乎每个包含字符a,b,c,d,e,f,i和o的四个字母单词,并且使用过他们互相交谈.) (4认同)
  • 现在我渴望一些死牛肉. (2认同)