为何struct foo6在6字节足够时被填充至8字节?
为什么struct foo6的位域要填充到32位?
核心原因:位域绑定基础类型的存储单元
问题的关键在于C语言位域的底层规则:所有同类型的连续位域,会被打包在一个对应基础类型大小的存储单元里。这里的位域都是int类型,所以它们的存储单元大小是sizeof(int)(4字节=32位),并且这个单元必须对齐到int的地址边界(通常是4字节)。
逐段拆解内存布局
- 前两个成员:
short s占2字节,char c占1字节,累计用了3字节。 - 位域的存储单元:接下来的
flip、nybble、septet都是int位域,编译器会给它们分配一个4字节的int存储单元。由于前面已经用了3字节,为了让这个int单元对齐到4字节边界,实际会先补1字节填充(原作者的解释里把这个填充和位域内部的pad合并,直接从char c后开始放位域,用pad1凑满1字节)。 - 位域内部填充:
flip(1位) + nybble(4位)总共5位,补3位pad1凑成1字节(部分编译器的行为,避免位域跨不必要的字节边界)。- 剩下的
septet(7位)必须补25位pad2,凑满整个4字节的int存储单元——因为位域是依附于int类型的,不能只占用int单元的一部分空间。
- 结构体总大小对齐:结构体的总大小必须是成员中最大对齐要求的整数倍。这里
int的对齐要求是4字节,前面的3字节加位域的4字节总共7字节,会被补到8字节(下一个4的倍数),所以sizeof(struct foo6)是8。
纠正你的误解
你之前觉得只要对齐到short的2字节边界就够,但实际上:
- 位域的基础类型是
int,所以它的存储规则要遵循int的对齐和大小要求,而非short的。 - 结构体的最大对齐要求由所有成员(包括位域的基础类型)决定,
int的4字节对齐优先级高于short的2字节,所以总大小必须是4字节的整数倍。
内容的提问来源于stack exchange,提问作者bdmt
相关产品推荐
相关产品推荐

