这些空指针,还是地址为0的指针?

Meh*_*dad 18 c c++ null nullptr language-lawyer

如果我写

int zero = 0;

void *p1 = (void *)0;
void *p2 = (void *)(int)0;
void *p3 = (void *)(0 /*no-op, but does it affect the next zero?*/, 0);

void *p4 = (void *)zero;    // For reference, this is a pointer to address zero
void *p5 = 0;               // For reference, this is a null pointer
void *p6 = NULL;            // For reference, this is a null pointer
void *p7 = nullptr;         // For reference, this is a null pointer (C++11)

static const int static_zero_1 = 0;       // Is this a literal zero when used?
static const int static_zero_2 = 1 - 1;   // No "literals 0" per se... is it?
void *p8 = (void *)static_zero_1;   // I have seen weird substitution rules...
void *p9 = (void *)static_zero_2;   // do they apply for NULL too?
Run Code Online (Sandbox Code Playgroud)

其中p1,p2p3(编辑:我加p8p9)将空指针(即== NULL,可能是也可能不是零地址),以及他们的将是与零地址(可能是也可能不是指针== NULL)?

如果答案在C和C++中有所不同,那么它们中的每一个是什么?

小智 9

并用C完成Andy的答案:

从C99标准:

6.3.2.3指针

1指向void的指针可以转换为指向任何不完整或对象类型的指针.指向任何不完整或对象类型的指针可能会转换为指向void的指针并再次返回; 结果应该等于原始指针.

3 带有值0整型常量表达式或类似的表达式 void *,称为空指针常量.55)如果将空指针常量转换为指针类型,则保证将结果指针(称为空指针)与指向任何对象或函数的指针进行比较.

因此,任何求值为的整型常量表达式0都是一个空指针常量,可以转换为NULL指针.在你的例子中,有效的所有指针除外p4,p8并且p9是空指针.p4,p8并且p9不必是空指针,因为它们的初始化不是常量表达式,因为它包含变量(即使const合格).

这是关于NULLC++ 的另一个答案,用于记录.


And*_*owl 8

其中p1,p2p3将空指针?

在C++ 11中,所有这些.根据C++ 11标准的第4.10/1段:

空指针常数是整数表达式(5.19),用于评估至零或类型的prvalue整数类型的prvalue std::nullptr_t.[...]

因此,根据该标准的术语,一切这是一个常数(积分)的表达和评估为0是一个空指针常量(不是空指针,还).唯一一个不是在您的示例中求值0或类型的值的常量表达式,因为它不是常量表达式.nullptr_tzero

该段继续:

空指针常量可以转换为指针类型; 结果是该类型的空指针值,并且可以与对象指针或函数指针类型的每个其他值区分开.这种转换称为空指针转换.相同类型的两个空指针值应相等.

所以在你的例子中,所有指针除了p4空指针值并且它们之间的比较相等.


Jam*_*nze 8

p1并且p2是空指针; p3是实现定义,可能是其他东西.(逗号运算符不能是常量表达式的一部分.并且非常量整数值0到指针的映射是实现定义的.)C与此处的C++相同.

p8并且p9都是C++中的空指针,但不是C.

关于你的评论static_zero_2,任何一种语言都没有要求任何地方存在字面零.克++定义NULL如内置编译器__null,例如,并且可以使用(1 - 1),或者'\0',或任何其他常量表达式评估为0.