I thought I understood how C/C++ handled struct member alignment. But I'm getting strange results for a particular arrangement in Visual Studio 2008 and 2010.
Specifically, I'm finding that a struct consisting of a char, short, and char is compiled into a 6-byte struct, even with 4- or 8-byte packing enabled. I am at a loss as to why this would be. I can understand a 4-byte struct. I could perhaps understand an 8-byte struct. But I would think that a 6-byte struct would be impossible when 4-byte packing is enabled.
A program that demonstrates the problem is:
#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;
}
The output is:
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 . . .
Can anyone explain why VC is padding each of those chars with an additional byte?
The Visual Studio's C compiler with this command option /Zp[n] where a struct is packed on a n-byte boundary, this is where the
#pragma pack
directive comes in, members of the structure are aligned on a boundary that is multiple of n.From the MSDN documentation for
#pragma pack
(wheren
is the value you set):sizeof(short)
is two bytes, which is smaller than the packing value of four bytes that you set, so theshort
member is aligned to a two byte boundary.The last
char
(c2
) is padded with an extra byte after it so that whenAlignment
objects are placed in an array, theshort
element is still correctly aligned on a two-byte boundary. Array elements are contiguous and there can be no padding between them, so padding must be added to the end of the structure in order to ensure proper alignment in arrays.Apparently, you indeed misunderstand it. In Visual Studio you cannot increase the alignment requirements for struct members of any type by using the struct packing settings. You can only decrease them.
If your struct consists of
char
(aligned at 1 byte boundary) andshort
(aligned at 2 byte boundary) objects, then using 4- and 8-byte packing settings will have absolutely no effect on the layout or size of your structure. The result will be exactly the same as with 2-byte packing. The structure will have size of 6 bytes.The only packing setting that will have any effect in this case is 1-byte packing setting which will decrease the alignment requirement of
short
from 2 to 1 and result in 4 byte size of the structure.