nullptr
我在一行 C 代码中包含了一个检查。编译器(gcc)在使用-std=c17
以及-std=gnu17
.
现代 C 标准中是否有 nullptr (或等效项)之类的东西?(C11, C17)
如果不是,那为什么?
不,C 仍然使用NULL
空指针。
C++ 需要一个专用的空指针文字,因为它具有重载和模板类型推导。这些特性被NULL
, 扩展为0
C++ 中的(或类似的东西)混淆了。但是,在 C 中这种混淆的风险很小(可能_Generic
会因此而混淆),此外,C 可以使用(void*)0
空指针,这进一步降低了这种风险。
最接近 C++ 的nullptr
是 C 的NULL
. 这可能是
- 值为0的整数常量表达式,
- 将值 0 强制转换为 type 的整数常量表达式
void*
。空指针常量可以转换为任何指针类型;这种转换会产生该类型的空指针值。
正式的 C17 规范声明stddef.h
标头定义了NULL
“扩展为实现定义的空指针常量”。(7.19)空指针常量定义如下 (6.3.2.3)
- 值为 0 的整数常量表达式,或转换为 type 的此类表达式
void *
称为空指针常量。)如果将空指针常量转换为指针类型,则生成的指针(称为空指针)保证可以比较不等于指向任何对象或函数的指针。- 将空指针转换为另一种指针类型会产生该类型的空指针。任何两个空指针应该比较相等。
请注意,这会使以下程序模棱两可,NULL
可能是整数常量表达式(函数接受)或类型void*
(函数不接受)。
#include <stdio.h>
void printInt(int n)
{
printf("%d\n", n);
}
int main(void)
{
printInt(NULL);
}
这就是nullptr
在 C++11 中引入的原因。对于没有函数重载或类型推导的 C,这不是一个问题。
C 中的空指针是指向“null”的指针对象。您可以通过将指针分配给空指针常量来将指针转换为空指针。有效的空指针常量是0
和(void*)0
。该宏NULL
保证为空指针常量。
然后指针的内部表示变成一个“空指针”,理论上它可以指向一个在某些奇异系统上不同于零的地址。类似地,NULL
理论上可以扩展到旧的、准标准 C 中不同于零的东西。
在创建 C++ 时,Bjarne Stroustrup 发现所有这些都是不必要的复杂,并决定“NULL 为 0”(来源:https ://www.stroustrup.com/bs_faq2.html#null )。值得注意的是,C++ 早在 C 的第一次标准化之前就已创建,因此他的论点与标准 C 的相关性不如与标准前的 C 相关。
有关 C 中空指针与 NULL 的更多信息,请参阅空指针和 NULL 有什么区别?