Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 不同编译器上结构与显式宽度成员的对齐_C_Struct_Offset_Member_Memory Address - Fatal编程技术网

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)