Bit Fields and Memory Alignment

Bit Fields and Memory Alignment

Using Visual C++ 6.0, I recently attempted to create a structure to implement a data message that my application had to process. The following code segment produced unexpected results (names have been changed to protect the innocent):

struct X{   BOOL field1 : 4;   BOOL field2 : 2;   BOOL field3 : 1;   BOOL field4 : 1;   BOOL field5 : 4;   BOOL field6 : 4;};struct Y{   BOOL field1 : 1;   BOOL field2 : 1;      ...   BOOL field10 : 1;   int  Spare   : 6;};struct message{   X messageField1;   Y messageField2;};

The structures X and Y were each packed into 16 bits, as I had intended. But the message structure took 64 bits, not 32. I included 16 bits of padding before messageField1 and messageField2. Changing BOOL to unsigned char fixed the problem.

Can you explain this, please?

Almost everything about bit-fields is compiler- and platform-dependent. In your example, BOOL appears to be the culprit. BOOL is synonymous with “signed int.” As such, it requires 32-bit alignment on Win32. This means that bit structures that contain less than 32 bits may get additional padding bytes to make them fit into a 32-bit word boundary.

When you define a bit field structure that occupies a total of 16 bits or less, always use char or short. Choosing a larger integral type can cause the insertion of extra padding bytes. Furthermore, using a signed type such as BOOL to define a one-bit field is a bad idea, and it likely will cause unexpected results because a signed field always reserves one bit for the sign. If you need a signed bit field, use at least two bits. Otherwise, use an unsigned type explicitly:

struct BITS{ unsigned char f1: 1; // possible values: 0,1 signed char f2: 2 // possible values: -1,0,1};


Share the Post: