Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does a struct consisting of a char, short, and char (in that order), when compiled in C++ with 4-byte packing enabled, come to a 6-byte struct?

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?

like image 538
OldPeculier Avatar asked Nov 30 '22 09:11

OldPeculier


1 Answers

From the MSDN documentation for #pragma pack (where n is the value you set):

The alignment of a member will be on a boundary that is either a multiple of n or a multiple of the size of the member, whichever is smaller.

sizeof(short) is two bytes, which is smaller than the packing value of four bytes that you set, so the short member is aligned to a two byte boundary.

The last char (c2) is padded with an extra byte after it so that when Alignment objects are placed in an array, the short 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.

like image 92
James McNellis Avatar answered Dec 05 '22 07:12

James McNellis