【发布时间】:2020-01-10 10:47:38
【问题描述】:
C 11 标准将结构兼容性定义如下(6.2.7):
此外,如果它们的标签和成员满足以下要求,则在单独的翻译单元中声明的两种结构、联合或枚举类型是兼容的:如果用标签声明了另一种,则应使用相同的标签声明另一种。如果两者都在各自翻译单元内的任何地方完成,则适用以下附加要求:它们的成员之间应存在一一对应关系,以便每对对应的成员都声明为兼容的类型……
这意味着我可以有 2 个这样的文件:
foo.c:
struct struc {
int x;
};
int foo(struct struc *s)
{
return s->x;
}
main.c:
struct struc {
float x;
};
int foo(struct struc *s);
int main(void)
{
return foo(&(struct struc){1.2f});
}
闻起来像未定义的行为(就像 int 和 float 这样的类型一样)。但如果我正确理解标准(也许我误解了第二句话),这是允许的。如果是这样,这背后的理由是什么?为什么不同时指定单独翻译单元中的结构也必须在结构上等效?
【问题讨论】:
-
int和float就标准而言不是“兼容类型”。 -
它确实指定它们在结构上是等效的(“相应的成员被声明为兼容的类型”)——并且成员名称是相同的(它谈到了缺少的其余部分中的名称最后一句)。
-
@PSkocik 但是不是说结构对等仅在它们都在同一个翻译单元中完成时才适用吗?
-
@WingerSendon “如果两者都在各自的翻译单元内完成”。您在 foo.c 中的
struct struc已完成(==不仅仅是前向声明)并且您在 main.c 中的struct struc已完成:struct struc均在各自的翻译单元内完成。 -
标准说的是“各自的”,而不是“无关的”。引用其他人(或委员会或文件)时,请注意准确引用(或用“…”表示遗漏或用括号重新措辞/解释)。
标签: c types language-lawyer