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

C语言中两种结构体指针访问写法是否违反严格别名规则?

两种写法是否违反C语言严格别名规则?

先明确C语言严格别名规则的核心:一个对象只能通过与其兼容的类型指针、void*、char/unsigned char类型指针,或者符合特定例外的指针来访问,否则会违反规则,可能导致未定义行为。

第一种写法:违反严格别名规则

typedef struct{
    int type;
}foo_t;

foo_t *foo = foo_init();

*(int*)foo = 1;

这里将foo_t*强制转换为int*后解引用赋值,相当于把类型为foo_t的对象当成int类型对象来访问。foo_t和int属于完全不兼容的类型,也不在严格别名规则允许的例外范围内,因此这种写法违反了严格别名规则,编译器可能会做出优化导致程序行为异常。

第二种写法:不违反严格别名规则

typedef struct{
    int type;
}bar_t;

typedef struct{
    bar_t header;
}foo_t;

foo_t *foo = foo_init();

((bar_t*)foo)->type = 1;

C标准明确规定:指向结构体对象的指针可以转换为指向其第一个成员的指针,反之亦然,且两者的地址完全相同。这里bar_t是foo_t的第一个成员,所以把foo_t*转成bar_t*是合法的,后续通过bar_t*访问其type成员,本质是访问foo_t对象的第一个成员,完全符合严格别名规则的例外情况,因此这种写法不违反规则。

第二种写法更常见的原因

第二种写法之所以普及,核心是它合法规避了严格别名问题,同时这种“结构体嵌套头部”的写法是C语言中实现多态风格(类似面向对象的基类继承)的常用手段——通过统一的头部结构体标识对象类型,方便后续的类型判断和转换,不仅语法清晰,更重要的是符合标准规范,不会触发未定义行为。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 12:45:42