offsetof的此实现是否会调用未定义的行为?

JL2*_*210 1 c offsetof undefined-behavior

offsetof定义如下stddef.h

#define offsetof(type, member) ((size_t)&((type *)0)->member)
Run Code Online (Sandbox Code Playgroud)

是否由于取消引用NULL指针而调用未定义的行为?如果没有,为什么?

Eri*_*hil 5

在普通的C代码中,((size_t)&((type *)0)->member)C标准未指定的行为:

  • 首先,的每个C 2018 6.5.2.3 4,约->((type *)0)->member表示该部件的左值member的结构,其中的(type *)0点。但是((type *)0)没有指向结构,因此没有成员可以作为其左值。
  • 假设它确实为某个假设结构提供了一个左值,则不能保证将其地址转换为该地址会size_t产生该成员的偏移量,这两者都是因为我们不知道(type *)0在实现的寻址中会产生一个实际用零表示的地址方案,因为将指针转换为C 2018 6.3.2.3 6指定的整数仅告诉我们结果是实现定义的,而不是以任何其他有意义的形式产生地址。

如果此代码位于标准标头中,例如<stddef.h>,它是在C实现的控制下而不是在C标准的控制下,因此关于是否根据C标准未定义的问题不适用。C标准仅说明标准标头在包含时的行为-实现可以使用它选择的任何方式来实现所需的效果,无论是仅定义C标准未完全定义的源代码的行为还是放入源代码标头中的语言完全不同。(实际上,文件stddef.h可能完全为空或根本不存在,并且编译器可以在看到时提供所需的声明,#include <stddef.h>而无需从磁盘读取任何实际文件。)

  • @zwol假设`member`类型为`int`,并且位于结构中的偏移量'x`上,不是`&ptr-&gt; member`等效于`&*(int *)((char *)ptr + x )`? (2认同)