Alignment of bit-fields
You can declare a bit-field as a 
_Bool
, 
bool, char, signed char, unsigned
char, short, unsigned short
, int, unsigned int, long,
unsigned long, 
long long, or unsigned long long
data type. The alignment of a bit-field depends on its base
type and the compilation mode (32-bit or 64-bit).
In 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.
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.
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
longin 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.
An aggregate that contains only zero-length bit-fields has a length of 0 bytes and an
alignment of 4 bytes.
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).
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.
An aggregate that contains only zero-length bit-fields has a length of 0 bytes.
An aggregate that contains only zero-length bit-fields has the length of 1 byte.
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 |