如果我写
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?
p1
,p2
和p3
(编辑:我添加p8
和p9
)中的哪一个< em>空指针(即== NULL
,可能是也可能不是地址为零),以及哪些是地址为零的指针(可能是也可能不是== NULL
)?< / p>
如果答案在C和C ++中有所不同,那么它们中的每一个是什么?
答案 0 :(得分:9)
让Andy的答案完成C:
6.3.2.3指针
1指向void的指针可以转换为指向任何不完整或对象的指针 类型。指向任何不完整或对象类型的指针可以转换为指向void的指针 又回来了;结果应该等于原始指针。
3 整数常量表达式,其值为
0
,或者这样的表达式强制转换为类型void *
被称为空指针常量。 55)如果空指针常量转换为a 指针类型,结果指针,称为空指针,保证比较不等 指向任何对象或函数的指针。
因此任何整数常量表达式的计算结果为0
都是一个空指针常量,可以转换为NULL
指针。实际上,在您的示例中,除p4
,p8
和p9
之外的所有指针都是空指针。 p4
,p8
和p9
不需要是空指针,因为它们的初始化不是常量表达式,因为它包含变量(即使const
合格)。
答案 1 :(得分:8)
p1
,p2
和p3
中哪些是空指针?
在C ++ 11中,所有这些。根据C ++ 11标准的第4.10 / 1段:
空指针常量是整数类型的整数常量表达式(5.19)prvalue,其值为: 零或
std::nullptr_t
类型的prvalue。 [...]
因此,根据标准的术语,所有常量(整数)表达式并且评估为0
的是空指针常量(还不是空指针。在示例中,唯一不是常量表达式(0
或prvalue类型nullptr_t
的{{1}}是zero
,因为它不是常量表达式。
该段继续:
空指针常量可以转换为指针类型;该 result是该类型的空指针值,并且可以与对象指针的每个其他值区分开来 函数指针类型。这种转换称为空指针转换。两个空指针值 相同类型应相等。
因此,在您的示例中,除p4
之外的所有指针都是空指针值并且它们之间的比较相等。
答案 2 :(得分:8)
p1
和p2
是空指针; p3
是实现定义的,
并可能是别的东西。 (逗号运算符不能成为其中的一部分
一个恒定的表达。并且映射为非常数
指针的整数值0是实现定义的。)C是
这里与C ++相同。
p8
和p9
都是C ++中的空指针,但不是C中的。
关于您对static_zero_2
的评论,没有
在任何一种语言中要求字面为零,
任何地方。 g ++定义NULL
作为编译器内置__null
,
例如,您可以使用(1 - 1)
或'\0'
或其他任何内容
常数表达式评估为0.