为什么一个由char,short和char(按此顺序)组成的结构,当用C++编译并启用4字节打包时,会产生一个6字节的结构?

Old*_*ier 4 c++ struct packing memory-alignment visual-c++

我以为我理解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;
}
Run Code Online (Sandbox Code Playgroud)

输出是:

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 . . .
Run Code Online (Sandbox Code Playgroud)

任何人都可以解释为什么VC用一个额外的字节填充每个字符?

Jam*_*lis 17

MSDN文档中#pragma pack(n您设置的值在哪里):

成员的对齐将在边界上,该边界是n成员大小的倍数或倍数,以较小者为准.

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

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