C2x,6.5.3.2地址和间接操作符,语义,3:
,一元&运算符产生它的操作数的地址。
一个简单的问题:一元&运算符能产生地址0 (空指针)吗?
有任何例子/经验吗?
发布于 2022-02-16 00:28:53
C 2018年6.5.3.2 1说:
一元
&运算符的操作数应该是函数指示符、[]或一元*运算符的结果,或者是指定非位字段…的对象的lvalue。
如果操作数是函数指示符,它就不能是空指针,因为C 2018 6.3.2.3 3表示空指针“保证与指向任何对象或函数的指针不相等”,但是函数指示符如果是空指针,则等于另一个(可能不同)空指针,因为C 2018 6.5.9 6表示两个空指针比较相等。
如果它是一个指定对象的lvalue,那么它就不能是一个空指针,原因是相同的。(请注意,6.5.3.2 1具体指的是指定对象的lvalue。通常,lvalue是潜在的指定对象的表达式。也就是说,它必须有一个对象类型。但是,6.5.3.2 1中的约束明确地告诉我们操作数必须实际指定一个对象)。
这就留下了[]或一元*的结果。前者是用后者来定义的,所以我们只需要考虑一元*。C 2018 6.5.3.2 2表示“一元*运算符的操作数应该具有指针类型”,但它不要求它指向实际的对象或函数或非空。6.5.3.2 4说“…”如果操作数指向一个函数,则结果是一个函数指示符;如果它指向一个对象,则结果是一个指定对象…的值“。但没有明确说明如果操作数是空指针,结果是什么。它接着说:“如果向指针分配了无效的值,那么一元*运算符的行为是未定义的。”那里的文本提到了注释106,上面写着“…”在一元*操作符取消引用指针的无效值中,包括空指针、针对所指向对象类型的不正确对齐地址以及对象生存期结束后的地址。“
因此,C标准没有定义一元&将产生空指针的行为。当然,它可能是通过标准未定义的行为发生的。
发布于 2022-02-15 23:11:24
它可以。但你得尽你所能让它成为可能。
对于实际对象,有两种方法可以做到这一点:
请注意,这两种方法都来自于便携C,这就是重点所在。如果你让&返回NULL,你就会知道你做到了。这不是偶然发生的。
但是,还有另一种方法:我们可以构造一个表达式,该表达式不包含&返回0的实际对象。如下所示:
&(((struct some_struct *)0)->first_member)只在
#define offsetof(type, member) ((size_t)&(((type *)0)->member))不要这样做。#include <stddef>并让编译器定义offsetof。在这个实现中有一个bug。
发布于 2022-02-15 23:07:54
该标准的相关部分为6.3.2.3/3 (N2731),其中规定
如果将空指针常量转换为指针类型,则保证结果指针(称为空指针)与指向任何对象或函数的指针不相等。
因此,&对任何对象的作用结果都保证与空指针“比较不平等”。
https://stackoverflow.com/questions/71134484
复制相似问题