c++ 为什么不调用nullptr NULL?

pcww981p  于 2022-12-24  发布在  其他
关注(0)|答案(7)|浏览(171)

在C++11中,nullptr关键字被添加为一个更类型安全的空指针常量,因为之前NULL作为0的常见定义存在一些问题。
为什么标准委员会选择不调用新的空指针常量NULL,或者声明NULL应该是#define d to nullptr

kx5bkwkv

kx5bkwkv1#

Stephan T. Lavavej(C++标准委员会成员)解释说,一旦在talk(55:35)中:
虽然允许#define NULL nullptr的实现,但它会破坏相当多的使用,如

int i = NULL;

很明显,这样的人很多,所以他们不能强迫改变。

ru9i0ody

ru9i0ody2#

nullptr指针类型,而NULL倾向于整型,有时在重载函数中,您需要清楚您使用的是指针而不是整型-这正是nullptr派上用场的时候。
因此,要真正回答您的问题,NULLnullptr有两个不同的用途,将一个重新定义为另一个可能会破坏现有代码库中的许多内容。
除此之外,请查看Bjarne Stroustrup的网站:

我应该使用NULL还是0?

在C中,NULL的定义是0,所以只有美学上的区别。我更喜欢避免宏,所以我使用0。NULL的另一个问题是,人们有时会错误地认为它不同于0和/或不是整数。在标准之前的代码中,NULL有时被定义为不合适的东西,因此必须避免。现在这种情况已经不常见了。如果你必须给空指针命名,称之为空指针;在C11中是这么叫的,那么nullptr就是一个关键字。

p8ekf7hl

p8ekf7hl3#

NULL不是类型安全的。由于历史原因,它在没有强制转换的情况下被定义为0,并且编译器对将数字强制转换为此特殊零上的指针的警告静音。
对于即时,您可以执行以下操作:

void* p = 0;

但这不是没有隐式强制转换的情况:

void* p = 1234;

副作用是,它可能被滥用为数值,如其他答复所述。
nullptr通过强制它是一个指针来改进这一点,你不能把它赋给一个整数。由于行为改变了,为了向后兼容,创建了一个新的名称。
还要注意,nullptr由编译器处理,其实际值不会暴露给用户(如NULL为零)。使用架构相关值(如0xdeadbeef)要容易得多,而不会影响程序员的代码逻辑。

5t7ly7z5

5t7ly7z54#

如果没有参加标准委员会的讨论,很难说清楚,但我认为这是因为它会破坏一些使用NULL的代码,而nullptr的含义并不充分兼容。

krcsximq

krcsximq5#

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

可能是因为新的空指针是关键字,而关键字不能是#defined,所以将其称为NULL会使包含的任何C头都可能是格式错误的。

还是声明NULL应为#definednullptr

标准委员会确实允许NULL#definednullptr,但并不要求这样做。

C++11 18.2类型[支持.类型]/2:宏NULL是本国际标准中实现定义的C空指针常量。
**C
11 4.10指针转换[转换指针]/1**:一个 *null指针常量 * 是一个整型常量表达式(5.19),它的值是0或者是std::nullptr_t类型的纯右值。

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

e4eetjau

e4eetjau6#

我将演示一个案例,其中将nullptr定义为不同类型的决定有助于防止bug。
考虑以下函数:

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

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

在C++98中,上面的代码调用了foo(int)函数,因为NULL被替换为0,这很可能不是您想要的。
但是如果你调用foo(nullptr),它就会调用正确的函数--*foo(char)**。

dm7nw8vv

dm7nw8vv7#

引入nullptr是为了类型安全和清晰(可能是为了停止使用NULL初始化非指针类型)。
NULL(int类型)未更改为nullptr(指针类型),以避免混淆并确保向后兼容性。
因此,标准委员会的思路可能与从旧符号到新符号的平稳过渡有关,而不会引起歧义或破坏任何现有代码。

相关问题