为什么C++编译器允许将0赋值给指针,而不允许赋其他数字?

3

我正在回答一个问题,并评论到,多亏了名为metal的另一位发帖人,C++编译器允许这样做:

int *p = 0;,但不允许这样做:int *p = 1。是否认为0是一个特殊的数字?

编辑:@DavidHefferman说在指针的上下文中,0是特殊的吗?是的。 - 为什么?


2
0是特殊的吗?在指针的上下文中,是的,它是特殊的。 - undefined
它确实允许 int* p = (int*)1;。这将把 1 赋值给 int* p0 不需要类型,而其他所有值都需要。这就是它的特殊之处。 - undefined
1
@StarPilot 这并不是整个故事。int *p = 0; 是被定义和有用的,并且总是有效的,而 int *p = (int *)1; 最多只能说是实现定义(我不确定,它可能也是未定义行为),几乎总是无用的,几乎总是完全错误的。 - user395760
2
最后,唯一正确的答案是:因为标准这么规定的。从历史上看,C语言的创造者们忘记提供空指针。而最初的实现允许将整数隐式转换为指针,所以人们习惯使用0作为空指针常量。C++对此进行了规范化,但限制了只能将整数常量评估为0,并且C的标准委员会采纳了C++的规范化(并增加了一个额外的合法可能性)。 - undefined
2
@StarPilot 不行。 0int 类型的。总是如此。但是C++,就像C一样,有很多隐式转换。这个特别之处在于它只适用于“求值为0的整数表达式”。(注意,NULL可以定义为(1-1),虽然我从未见过。而且很长时间以来,g++将其定义为__builtin__nullptr,或类似的编译器特定的整数表达式,它可以识别并生成警告,如果它不立即被转换为指针类型的话。) - undefined
显示剩余2条评论
3个回答

6
标准的第4.10节,指针转换[conv.ptr]说:
空指针常量是一个整数类型的整数常量表达式(5.19)prvalue,其求值为零或std :: nullptr_t类型的prvalue。空指针常量可以转换为指针类型;结果是该类型的空指针值,并可区分于对象指针或函数指针类型的每个其他值。这种转换称为零指针转换。相同类型的两个空指针值应相等。将空指针常量转换为cv限定类型的指针是单一转换,而不是指针转换后跟资格转换(4.4)的序列。整数类型的空指针常量可以转换为std :: nullptr_t类型的prvalue。
因此,在指针的上下文中,0是一个特殊值。

6分钟内接受的答案 - undefined
3
请注意,常量表达式很重要--例如,类似于int i=0; int *p=i;的东西将不会起作用,因为i不是一个常量表达式(即使从阅读它时很明显它将始终包含值0)。 - undefined
@JerryCoffin 当然,你可以使用reinterpret_cast来强制转换。但即使如此,转换的结果可能与将空指针常量转换得到的结果不同。 - undefined
在C++20标准中,该部分是7.3.12。 - undefined

1

0表示空,而1表示无效地址。


1

即数字0是一个空指针常量,因此可以直接赋值给指针而无需显式类型转换。 - user308323

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接