Alignment of bit-fields

You can declare a bit-field as a C_BoolC, C++bool, char, signed char, unsigned char, short, unsigned shortC++, int, unsigned int, long, unsigned long, C++long long, or unsigned long longC++ data type. The alignment of a bit-field depends on its base type and the compilation mode (32-bit or 64-bit).

CIn the C language, you can specify bit-fields as char or short instead of int, but XL C/C++ maps them as if they were unsigned int. The length of a bit-field cannot exceed the length of its base type. In extended mode, you can use the sizeof operator on a bit-field. The sizeof operator on a bit-field returns the size of the base type.C

C++The length of a bit-field can exceed the length of its base type, but the remaining bits are used to pad the field and do not actually store any value.C++

However, alignment rules for aggregates containing bit-fields are different depending on the alignment mode in effect. These rules are described below.

Rules for natural alignment

  • A zero-length bit-field pads to the next alignment boundary of its base declared type. This causes the next member to begin on a 4-byte boundary for all types except long in 64-bit mode, which moves the next member to the next 8-byte boundary. Padding does not occur if the previous member's memory layout ended on the appropriate boundary.
  • CAn aggregate that contains only zero-length bit-fields has a length of 0 bytes and an alignment of 4 bytes.C
  • C++An aggregate that contains only zero-length bit-fields has a length of 4 or 8 bytes, depending on the declared type of the bit-field and the compilation mode (32-bit or 64-bit).C++

Rules for power alignment

  • Aggregates containing bit-fields are 4-byte (word) aligned.
  • Bit-fields are packed into the current word. If a bit-field would cross a word boundary, it starts at the next word boundary.
  • A bit-field of length zero causes the bit-field that immediately follows it to be aligned at the next word boundary, or 8 bytes, depending on the declared type and the compilation mode. If the zero-length bit-field is at a word boundary, the next bit-field starts at this boundary.
  • CAn aggregate that contains only zero-length bit-fields has a length of 0 bytes.C
  • C++An aggregate that contains only zero-length bit-fields has the length of 1 byte.C++

Rules for Mac68K alignment

  • Bit-fields are packed into a word and are aligned on a 2-byte boundary.
  • Bit-fields that would cross a word boundary are moved to the next halfword boundary even if they are already starting on a halfword boundary. (The bit-field can still end up crossing a word boundary.)
  • A bit-field of length zero forces the next member (even if it is not a bit-field) to start at the next halfword boundary even if the zero-length bit-field is currently at a halfword boundary.
  • An aggregate containing nothing but zero-length bit-fields has a length, in bytes, of two times the number of zerolength bit-fields.
  • For unions, there is one special case: unions whose largest element is a bit-field of length 16 or less have a size of 2 bytes. If the length of the bit-field is greater than 16, the size of the union is 4 bytes.

Rules for bit-packed alignment

  • Bit-fields have an alignment of one byte and are packed with no default padding between bit-fields.
  • A zero-length bit-field causes the next member to start at the next byte boundary. If the zero-length bit-field is already at a byte boundary, the next member starts at this boundary. A non-bit-field member that follows a bit-field is aligned on the next byte boundary.

Example of bit-packed alignment

#pragma align=bit_packed
struct {
   int a : 8;
   int b : 10;
   int c : 12;
   int d : 4;
   int e : 3;
   int : 0;
   int f : 1;
   char g;
   } A;

pragma align=reset     

The size of A is 7 bytes. The alignment of A is 1 byte. The layout of A is:

Member name Byte offset Bit offset
a 0 0
b 1 0
c 2 2
d 3 6
e 4 2
f 5 0
g 6 0