为什么 struct/union 兼容性需要标记和名称相等?

Why is tag and name equality required for struct/union compatibility?

C99 标准在第 6.2.7.1 节中有以下语言:

two structure, union, or enumerated types declared in separate translation units are compatible if their tags and members satisfy the following requirements: If one is declared with a tag, the other shall be declared with the same tag. If both are complete types, then the following additional requirements apply: there shall be a one-to-one correspondence between their members such that each pair of corresponding members are declared with compatible types, and such that if one member of a corresponding pair is declared with a name, the other member is declared with the same name. For two structures, corresponding members shall be declared in the same order. For two structures or unions, corresponding bit-fields shall have the same widths. For two enumerations, corresponding members shall have the same values. (emphasis added)

特别是,此规则使这两个具有相同布局的 struct 不兼容,因为它们的标签和成员名称不匹配:

struct x_type {
    int x;
};

struct y_type { // << Different tag
    int y;      // << Different member name
};

很容易理解为什么成员类型和它们的声明顺序必须相同。然而,不清楚为什么标签和成员名称也需要匹配,即使它们不影响 struct?

的二进制布局

您引用的文字不是在谈论与布局兼容的类型,而是在谈论相同类型的类型。该规则是 C 如何定义一个类型的两个定义是否是同一类型的有效重新定义。

在你的例子中你是对的 x_typey_type 不兼容,因为它们描述的肯定不是同一类型!如果它们兼容,则意味着使用 struct y_type* 类型的参数调用 void foo(struct x_type*) 将是有效的,这当然不是本意。

您引用的文字和以下段落是 C++ ODR 的 C 等价物,要求标签和成员名称相同类似于 [basic.def.odr] 中的措辞:

Given such an entity named D defined in more than one translation unit, then

— each definition of D shall consist of the same sequence of tokens; and
— in each definition of D, corresponding names, looked up according to 3.4, shall refer to an entity defined within the definition of D, or shall refer to the same entity, after overload resolution (13.3) and after matching of partial template specialization (14.8.3), [...]