C 不同编译器上结构与显式宽度成员的对齐
我想知道,如果结构是手动填充的,那么每个成员都以其大小的倍数对齐,并且所有对象都具有已知的显式宽度,那么我能期望二进制布局在多大程度上完全是“预期的”/“预期的”?也许有一些特定于编译器的选项可以确保布局与声明的完全一致C 不同编译器上结构与显式宽度成员的对齐,c,struct,offset,member,memory-address,C,Struct,Offset,Member,Memory Address,我想知道,如果结构是手动填充的,那么每个成员都以其大小的倍数对齐,并且所有对象都具有已知的显式宽度,那么我能期望二进制布局在多大程度上完全是“预期的”/“预期的”?也许有一些特定于编译器的选项可以确保布局与声明的完全一致 IIRC C标准不允许任何重新排序,因此只有最终的额外填充是有问题的。如果根据结构自身的对齐规则对其进行填充,编译器是否需要添加填充?您可以在代码中通过以下方式指定强制填充:例如:\uuuuu属性(对齐(16)) 我认为还有另一个属性名packed,用于指定您不希望编译器对齐您
IIRC C标准不允许任何重新排序,因此只有最终的额外填充是有问题的。如果根据结构自身的对齐规则对其进行填充,编译器是否需要添加填充?您可以在代码中通过以下方式指定强制填充:例如:
\uuuuu属性(对齐(16))代码>
我认为还有另一个属性名packed
,用于指定您不希望编译器对齐您的结构。
有关详细信息,请参见此默认情况下,编译器将对齐到32或64位。
是的,有一些特定于编译器的选项可以将对齐设置为自定义值
因此,如果要控制结构字段的对齐,可以使用编译器标志或pragmas来实现
对于GCC,它将是-fpack struct=[n]
在源代码中,您可以使用#pagma pack
或#pagma push(pack)
围绕结构的定义:
GCC文件:
MSDN文档:
(我可能错了,但是)我不知道标准中有什么要求填充最小的内容。考虑到这一点,编译器似乎有权在成员之间和结构的末尾(但不是开头)放置任意数量的填充,即使该填充不是满足对齐要求所必需的。因此,手动填充到32或64位并不能保证阻止编译器添加填充,即使它可能对所有实际编译器都是如此
正如其他人所指出的,有一些特定于编译器(即非标准)的方法可以强制结构完全没有编译器提供的填充,但不能控制填充
即使您可以精确地指定填充,您仍然没有精确地定义结构内容,因为您没有定义成员的表示(例如,大端或小端整数),因此我不确定您从中获得了什么,特别是在需要可移植性的情况下。您已经精确地定义了成员的偏移量,但没有定义它们的表示形式。请注意,类型可能有与其大小不同的对齐要求。@nos-我的意思是仅针对基本体。结构是另一回事。@nos-你能举个例子吗?
#pragma pack(push(n))
typedef struct my_struct {...} my_struct_t;
#pragma pack(pop)