无填充结构体转整数:小端平台是否合法且无未定义行为?
struct test { char a, b, c, d; }; int main(){ struct test t = {1,2,3,4}; int d = *(int*)&t; assert(d == 67305985); return 0; }
在小端平台上,这段代码依然存在未定义行为,并不合法,核心原因有两点:
- 违反严格别名规则:C标准明确规定,除非是
char*,否则不能用一种类型的指针去访问另一种类型的对象。这里把struct test*强制转换成int*后解引用,本质是用int类型的视角去访问结构体类型的对象,直接违反了这条规则,属于标准定义的未定义行为。 - 对齐风险:int类型通常有严格的对齐要求(比如多数平台要求4字节对齐),而这个结构体因为成员都是1字节的char,它的对齐要求可能仅为1字节。如果
&t的地址不满足int的对齐要求,解引用(int*)&t会触发对齐错误,这也是未定义行为的一种。
哪怕小端平台下结构体的内存布局刚好能让断言成立(计算值确实是67305985),但从C标准的角度,这段代码的行为依然不受保障——编译器可能依据严格别名规则做优化,导致运行结果不符合预期。
内容的提问来源于stack exchange,提问作者Dan
相关产品推荐
相关产品推荐

