4

我以为我了解 C/C++ 如何处理结构成员对齐。但是对于 Visual Studio 2008 和 2010 中的特定安排,我得到了奇怪的结果。

具体来说,我发现由 char、short 和 char 组成的结构被编译为 6 字节结构,即使启用了 4 或 8 字节打包也是如此。我不知道为什么会这样。我可以理解一个 4 字节的结构。我也许可以理解一个 8 字节的结构。但是我认为当启用 4 字节打包时,6 字节结构是不可能的。

演示该问题的程序是:

#include <iostream>
using namespace std;

#pragma pack (4)

struct Alignment
{
 char c1;
 short s;
 char c2;
};

#define REPORT_VAR_POSITION( structName, varName ) cout << "Member '" << #varName << "' sits at byte # " << offsetof( structName, varName ) << "." << endl;

int main(int argc, char* argv[])
{
 cout << "Sizeof struct Alignment is " << sizeof( Alignment ) << " bytes." << endl;
 REPORT_VAR_POSITION( Alignment, c1 );
 REPORT_VAR_POSITION( Alignment, s );
 REPORT_VAR_POSITION( Alignment, c2 );

 system( "pause" );

 return 0;
}

输出是:

Sizeof struct Alignment is 6 bytes.
Member 'c1' sits at byte # 0.
Member 's' sits at byte # 2.
Member 'c2' sits at byte # 4.
Press any key to continue . . .

谁能解释为什么 VC 用一个额外的字节填充每个字符?

4

3 回答 3

17

MSDN 文档#pragma packn您设置的值在哪里):

成员的对齐方式将位于成员n大小的倍数或倍数的边界上,以较小者为准。

sizeof(short)是两个字节,小于您设置的四个字节的打包值,因此该short成员对齐到两个字节边界。

最后一个char( c2) 在它之后用一个额外的字节填充,这样当Alignment对象被放置在一个数组中时,short元素仍然在两个字节的边界上正确对齐。数组元素是连续的,它们之间不能有填充,因此必须在结构的末尾添加填充,以确保数组中的正确对齐。

于 2010-09-03T18:00:19.960 回答
4

看来,你确实误会了。在 Visual Studio 中,您无法通过使用 struct 打包设置来增加任何类型的 struct 成员的对齐要求。你只能减少它们。

如果您的结构由char(在 1 字节边界对齐)和short(在 2 字节边界对齐)对象组成,那么使用 4 字节和 8 字节打包设置绝对不会影响结构的布局或大小。结果将与 2 字节打包完全相同。该结构的大小为 6 个字节。

在这种情况下,唯一会产生影响的打包设置是 1 字节打包设置,这会将对齐要求从 2降低short到 1,并导致结构的大小为 4 字节。

于 2010-09-03T18:06:32.050 回答
-1

带有此命令选项 /Zp[n] 的 Visual Studio 的 C 编译器,其中结构被打包在n字节边界上,这是#pragma pack指令的来源,结构的成员在 n 的倍数的边界上对齐。

于 2010-09-03T18:05:54.813 回答