You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

同一翻译单元中声明的兼容结构体类型有哪些要求?

同一翻译单元中C语言结构体类型的兼容规则解析

C11标准的相关规定

C11标准6.2.7节《兼容类型和复合类型》第1款指出:

此外,在不同翻译单元中声明的两个结构体、联合体或枚举类型,若其标签和成员满足以下要求,则为兼容类型:……

上述内容明确了不同翻译单元中结构体类型的兼容要求,那么同一翻译单元中声明的结构体类型,兼容规则是什么?

对比测试与结论

C++17标准(N4713)中有这样的说明:

例如,除标签名不同外完全相同的结构体类型在C中是“兼容”的,但在C++中是截然不同的类型。

我们可以通过一段测试代码验证C语言中的实际行为:

struct x { int x; } x;
struct y { int x; } *p = &x;

使用主流C编译器以C11标准编译这段代码,得到如下警告:

$ gcc t0.c -std=c11 -pedantic -Wall -Wextra
warning: initialization of 'struct y *' from incompatible pointer type 'struct x *' [-Wincompatible-pointer-types]

$ clang t0.c -std=c11 -pedantic -Wall -Wextra
warning: incompatible pointer types initializing 'struct y *' with an expression of type 'struct x *' [-Wincompatible-pointer-types]

$ icc t0.c -std=c11 -pedantic -Wall -Wextra
warning #144: a value of type "struct x *" cannot be used to initialize an entity of type "struct y *"

$ cl t0.c /std:c11
warning C4133: 'initializing': incompatible types - from 'x *' to 'y *'

从测试结果可以明确:在同一翻译单元中声明的、仅标签名不同但成员完全一致的结构体类型不兼容。

补充说明

此前有讨论聚焦于“不同翻译单元中结构体类型是否真的兼容”这一问题,这里不再展开外部讨论细节。

关于链接器的疑问

针对“链接器会判断类型是否兼容”的说法,我们做了如下测试:

foo.c

struct struc1 {
    int x;
};

int foo(struct struc1 *s)
{
    return s->x;
}

main.c

struct struc {
    float x;
};

int foo(struct struc *s);

int main(void)
{
    return foo(&(struct struc){1.2f});
}

执行编译命令后无任何报错:

$ gcc foo.c main.c -std=c11 -pedantic -Wall -Wextra
<nothing>

那么问题来了:为何链接器未报错?


内容的提问来源于stack exchange,提问作者pmor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 21:24:27