人们通常认为 offsetof() 可以应用于联合(您甚至可以在 SO 的几个问题中找到这种用法),但是,似乎从 C90 到现在的所有 C 规范都只说 offsetof() 宏支持结构。我现在正在看 Jens Gustedt 的《Modern C》一书,表 4.3 指定“struct”作为 offsetof() 第一个参数的类型。
那么,... offsetof() 是否正式支持联合?
这实际上是 C 规范中的一个缺陷,直到 C2x。这是在 C11 规范DR 496的缺陷报告中提出的,已在 C2x 中解决。
\n从C11 规范部分 \xc2\xa77.19 第 3 段中,定义offsetof:
\n\n\n
offsetof(type, member-designator)它扩展为具有 type 的整数常量表达式
\nsize_t,其值是从其结构开头(由 type 指定)到结构成员(由member-designator指定)的偏移量(以字节为单位)。类型和成员指示符应给定\n
static type t;然后表达式的
\n&(t.member-designator)计算结果为地址常量。(如果指定的成员是位字段,则行为未定义。)
类型参数被描述为“结构成员”,但表达式对于联合类型也是明确定义的(\xc2\xa76.7.2.1 第 16 段)。&(t.member-designator)这给编译器作者带来了歧义,因此大多数人选择允许offsetof联合。
在 C2x 规范中,这被重新措辞(粗体强调我的):
\n\n\n\n
offsetof(type, member-designator)它扩展为具有 type 的整数常量表达式
\nsize_t,其值是从任何类型为 type 的对象的开头到子对象(由member-designator指定)的偏移量(以字节为单位) 。类型和成员指示符应给定\n
static type t;然后表达式的
\n&(t.member-designator)计算结果为地址常量。如果指定的类型定义了新类型或者指定的成员是位字段,则行为未定义。
变化是:
\noffsetof在新类型声明上使用是未定义的行为offsetof回答“可以适用于工会”的问题: