It's often assumed that offsetof() can be applied to unions (you can even find such use in several questions here at SO), but, however, it seems like all the C specifications from C90 to nowadays only say the offsetof() macro supports structs. I was now taking a look at the "Modern C" book by Jens Gustedt, and table 4.3 specifies "struct" as the type of the first argument to offsetof().
So,... are unions officially supported by offsetof(), or not?
This is actually a defect in the C spec, up until C2x. This was brought up in a defect report for the C11 spec DR 496, which was resolved in C2x.
From the C11 spec section §7.19 paragraph 3, the definition for offsetof
:
offsetof(type, member-designator)
which expands to an integer constant expression that has type
size_t
, the value of which is the offset in bytes, to the structure member (designated by member-designator), from the beginning of its structure (designated by type). The type and member designator shall be such that given
static type t;
then the expression
&(t.member-designator)
evaluates to an address constant. (If the specified member is a bit-field, the behavior is undefined.)
The type argument is described as a "structure member", yet the expression &(t.member-designator)
is also well-defined for union types (§6.7.2.1 paragraph 16). This gave rise to ambiguity for compiler authors, so most have chosen to allow offsetof
on unions.
In the C2x spec this is reworded (bold emphasis mine):
offsetof(type, member-designator)
which expands to an integer constant expression that has type
size_t
, the value of which is the offset in bytes, to the subobject (designated by member-designator), from the beginning of any object of type type. The type and member designator shall be such that given
static type t;
then the expression
&(t.member-designator)
evaluates to an address constant. If the specified type defines a new type or if the specified member is a bit-field, the behavior is undefined.
With the changes being:
offsetof
on new type declarations is undefined behaviorTo answer the question of "can offsetof
be applied to unions":