这个 offsetof 的实现会调用未定义的行为吗? [英] Does this implementation of offsetof invoke undefined behavior?

查看:32
本文介绍了这个 offsetof 的实现会调用未定义的行为吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

offsetofstddef.h 中是这样定义的:

offsetof is defined like this in stddef.h:

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

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

Does this invoke undefined behavior due to the dereference of a NULL pointer? If not, why?

推荐答案

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

In normal C code, the behavior of ((size_t)&((type *)0)->member) is not specified by the C standard:

  • 首先,根据C 2018 6.5.2.3 4,关于->((type *)0)->member指定成员的左值<(type *)0 指向的结构的代码>成员.但是 ((type *)0) 不指向结构,因此没有成员 this 可以是其左值.
  • 假设它确实给出了某个假设结构的左值,则无法保证获取其地址并将其转换为 size_t 会产生成员的偏移量,这都是因为我们不知道 (type *)0 产生的地址在实现的寻址方案中实际上用零表示,并且因为将指针转换为 C 2018 6.3.2.3 6 指定的整数只告诉我们结果是实现-定义,而不是它以任何其他有意义的形式产生地址.
  • First, per C 2018 6.5.2.3 4, about ->, ((type *)0)->member designates the lvalue of the member member of the structure to which (type *)0 points. But ((type *)0) does not point to a structure, and therefore there is no member this can be the lvalue of.
  • Supposing it does give an lvalue for some hypothetical structure, there is no guarantee that taking its address and converting it to size_t yields the offset of the member, both because we do not know that (type *)0 yields an address that is actually represented with zero in the implementation’s addressing scheme and because the conversion of a pointer to an integer specified by C 2018 6.3.2.3 6 only tells us the result is implementation-defined, not that it yields the address in any otherwise meaningful form.

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

Were this code in a standard header, such as <stddef.h>, it is under the control of the C implementation and not the C standard, and so questions about whether it is undefined according to the C standard do not apply. The C standard only says how the standard headers behave when included—an implementation may use any means it chooses to achieve the required effects, whether that is simply defining the behavior of source code that is not fully defined by the C standard or putting source code in an entirely different language in the headers. (In fact, the file stddef.h could be entirely empty or not exist at all, and the compiler could supply its required declarations when it sees #include <stddef.h> without reading any actual file from disk.)

这篇关于这个 offsetof 的实现会调用未定义的行为吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆