结构体精准填充至指定大小:sizeof(Foo)是否必然等于SIZE?
咱们先从标准规定和实际应用两个层面来拆解这个问题:
sizeof(Foo) == SIZE C/C++标准并没有给这个等式打“包票”,但不保证的场景非常边缘。
核心原因是:标准只要求结构体的对齐要求不低于其所有成员的最大对齐要求,但允许实现为结构体施加更严格的对齐约束。举个例子,如果某编译器给struct Foo指定了一个比alignof(Foo*)更大的对齐值,而SIZE刚好不是这个对齐值的整数倍,那么编译器会在结构体末尾自动添加填充字节,把总大小提升到该对齐值的下一个倍数,此时sizeof(Foo)就会大于SIZE。
不过要明确:这种行为是实现定义的,不是标准强制要求的,属于编译器的可选扩展。
在我们日常接触的绝大多数平台(x86、x86_64、ARM、ARM64等)的默认编译设置中,sizeof(Foo) == SIZE是绝对成立的。
这些平台的默认对齐逻辑很简单:结构体的对齐要求等于其成员里对齐要求最高的那个值。而指针类型Foo*的对齐要求通常等于自身大小(也就是alignof(Foo*) == sizeof(Foo*))。由于SIZE是sizeof(Foo*)的正倍数,自然也是结构体对齐要求的整数倍,编译器不需要额外添加任何填充,结构体的总大小就恰好等于SIZE。
有没有常用平台的反例?
默认情况下几乎没有。但如果手动修改了编译器的对齐选项(比如GCC用-falign-struct=16强制结构体对齐到16字节,而sizeof(Foo*)=8、SIZE=8时),此时sizeof(Foo)会被提升到16,不等于SIZE——但这是人为调整编译参数导致的,并非平台原生行为。
一些小众的嵌入式或DSP平台可能存在特殊对齐规则,但这类平台不属于“常用平台”的范畴。
内容的提问来源于stack exchange,提问作者BeeOnRope

