我想知道,如果结构是手动填充的,那么每个成员都在其大小的地址对齐,并且所有对象都具有已知的显式宽度,我可以期望二进制布局在何种程度上完全是“预期的” /打算一个?也许有一些编译器特定的选项可以确保布局与声明完全一致?
IIRC C标准不允许任何重新排序,因此只有最终的额外填充才有问题。如果根据自己的对齐规则填充结构,编译器是否需要添加填充?
答案 0 :(得分:1)
默认情况下,编译器将对齐32或64位。 是的,有一些编译器特定的选项可以将对齐设置为自定义值。
因此,如果要控制struct字段的对齐,可以使用编译器标志或编译指示来执行此操作。
GCC为-fpack-struct=[n]
在源代码中,您可以使用#pagma pack
或#pagma push(pack)
包围结构的定义:
#pragma pack(push(n))
typedef struct my_struct {...} my_struct_t;
#pragma pack(pop)
海湾合作委员会文件: http://gcc.gnu.org/onlinedocs/gcc/Structure-Packing-Pragmas.html
MSDN文档: http://msdn.microsoft.com/en-us/library/2e70t5y1.aspx
答案 1 :(得分:0)
您可以在代码中指定强制填充,例如:__attribute__((aligned (16)));
我认为还有另一个属性名packed
来指定您不希望编译器对齐您的结构。
有关详细信息,请参阅此link
答案 2 :(得分:0)
(我可能错了,但是)我不知道标准中的任何内容要求填充是最小的。鉴于此,编译器似乎有权在成员之间和结构末尾(但不是在开头)放置任意数量的填充,即使不需要填充以满足对齐要求。因此,手动填充到32位或64位不能保证编译器添加填充,即使它可能适用于所有实际编译器。
正如其他人指出的那样,有一些特定于编译器的方法(即非标准方法)可以强制结构体根本没有编译器提供的填充,但不能控制填充。
即使你可以准确地指定填充,你仍然没有精确定义结构内容,因为你还没有定义成员的表示(例如big-or-endian整数),所以我不确定你从中获得了什么,特别是如果需要便携性的话。你已经精确地定义了成员的偏移量,但没有定义它们的表示。