繁体   English   中英

一元 & 运算符能否产生地址 0(空指针)?

[英]Can the unary & operator yield the address 0 (null pointer)?

C2x,6.5.3.2 地址和间接运算符,语义,3:

一元 & 运算符产生其操作数的地址。

一个简单的问题:一元运算符&可以产生地址0 (空指针)吗?

有什么例子/经验吗?

它可以。 但是您必须 go 才能使它成为可能。

对于实际的 object,有两种方法可以做到这一点:

  1. 构造一个 object 文件或 linker 符号文件,您要链接到该文件,并在 NULL 处导出一个符号。如果您 & 在上面,您将得到 NULL。

  2. 在某些平台上是 libc。 您定义的第一个符号是 NULL。至少在一个平台上,堆管理器必须应对此问题,因此对其进行了仔细编码,以便编译器永远不会观察到堆 HEAD 指针存储在 NULL 的事实。

请注意,这两个都在便携式C之外,这就是重点。 如果你得到&返回 NULL 你就会知道你做到了。 这不是偶然发生的。

但是还有另一种方法:我们可以构造一个不包含真实对象的表达式,其中&返回 0。像这样:

&(((struct some_struct *)0)->first_member)

只见于

#define offsetof(type, member) ((size_t)&(((type *)0)->member))

不要这样做。 #include <stddef>并让编译器定义offsetof 这个实现中有一个错误。

C 2018 6.5.3.2 1 说:

一元&运算符的操作数应为 function 指示符, []或一元*运算符的结果,或指定 object 不是位域的左值……

If the operand is a function designator, it cannot be a null pointer, since C 2018 6.3.2.3 3 says a null pointer “is guaranteed to compare unequal to a pointer to any object or function,” but a function designator that were a null指针将与另一个(可能不同的)null 指针比较,因为 C 2018 6.5.9 6 表示两个 null 指针比较相等。

如果它是指定 object 的左值,则出于同样的原因,它不能是 null 指针。 (请注意,6.5.3.2 1 特指指定一个 object 的左值。通常,左值是一个可能指定一个 object 的表达式。也就是说,它必须具有 object 类型。但是,6.5.3.2 1 中的约束特别告诉我们操作数必须实际指定一个 object。)

剩下[]或一元*的结果。 前者是根据后者定义的,所以我们只需要考虑一元* C 2018 6.5.3.2 2 说“一元*运算符的操作数应具有指针类型”,但并不要求它指向实际的 object 或 function 或非空。 6.5.3.2 4 表示“……如果操作数指向 function,则结果为 function 指示符; 如果它指向 object,则结果是指定对象的左值……”但没有明确说明如果操作数是 null 指针,结果是什么。 它继续说“如果为指针分配了无效值,则一元*运算符的行为未定义。” 那里的文本引用注释 106,它说“......在一元*运算符取消引用指针的无效值中,有一个 null 指针,一个地址与指向的 object 类型不适当对齐,以及 object 之后的地址生命周期结束。”

因此,C 标准没有定义一元&会产生 null 指针的行为。 当然,它可能通过标准未定义的行为发生。

该标准的相关部分是 6.3.2.3/3 (N2731),其中规定

如果将 null 指针常量转换为指针类型,则生成的指针(称为 null 指针)保证与指向任何 object 或 function 的指针比较不相等。

因此, &作用于任何 object 的结果保证与 null 指针“比较不相等”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM