我以为我理解了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用一个额外的字节填充每个字符?
答案 0 :(得分:16)
来自the MSDN documentation for #pragma pack
(其中n
是您设置的值):
成员的对齐将位于
n
的倍数或成员大小的倍数的边界上,以较小者为准。
sizeof(short)
是两个字节,小于您设置的四个字节的打包值,因此short
成员与两个字节的边界对齐。
最后char
(c2
)后面加一个额外的字节,这样当Alignment
个对象放在一个数组中时,short
元素仍然正确在两字节边界上对齐。数组元素是连续的,它们之间不能有填充,因此必须在结构的末尾添加填充,以确保数组中的正确对齐。
答案 1 :(得分:4)
显然,你确实误解了它。在Visual Studio中,您不能通过使用struct packing设置增加任何类型的struct成员的对齐要求。你只能减少。
如果你的结构由char
(在1字节边界对齐)和short
(在2字节边界对齐)对象组成,那么使用4和8字节打包设置将完全没有效果关于结构的布局或大小。结果与2字节打包完全相同。该结构的大小为6个字节。
在这种情况下唯一有效的打包设置是1字节打包设置,将short
的对齐要求从2减少到1并导致4字节大小结构。
答案 2 :(得分:-1)
使用此命令选项/ Zp [n]的Visual Studio的C编译器,其中结构打包在 n - 字节边界上,这是#pragma pack
指令所在的位置,成员结构的对齐是在n的倍数的边界上。