Bit fields are the only objects that are packed within a byte. That is, two bit fields can be stored in the same byte. Bit fields can range in size from 1 to 32 bits, but they never span a 4-byte boundary.
For big-endian mode, bit fields are packed into registers from most significant bit (MSB) to least significant bit (LSB) in the order in which they are defined. Bit fields are packed in memory from most significant byte (MSbyte) to least significant byte (LSbyte). For little-endian mode, bit fields are packed into registers from the LSB to the MSB in the order in which they are defined, and packed in memory from LSbyte to MSbyte.
Here are some details about how bit fields are handled:
- Plain int bit fields are unsigned. Consider the following C code:
struct st
{
int a:5;
} S;
foo()
{
if (S.a < 0)
bar();
}
In this example, bar () is never called as bit field 'a' is unsigned. Use signed int if you need a signed bit field.
- Bit fields of type long long are supported.
- Bit fields are treated as the declared type.
- The size and alignment of the struct containing the bit field depends on the declared type of the bit field. For example, consider the struct:
struct st {int a:4};
This struct uses up 4 bytes and is aligned at 4 bytes.
- Unnamed bit fields affect the alignment of the struct or union. For example, consider the struct:
struct st{char a:4; int :22;};
This struct uses 4 bytes and is aligned at a 4-byte boundary.
- Bit fields declared volatile are accessed according to the bit field's declared type. A volatile bit field reference generates exactly one reference to its storage; multiple volatile bit field accesses are not merged.
Figure 6-4 illustrates bit-field packing, using the following bit field definitions:
struct{
int A:7
int B:10
int C:3
int D:2
int E:9
}x;
A0 represents the least significant bit of the field A; A1 represents the next least significant bit, etc. Again, storage of bit fields in memory is done with a byte-by-byte, rather than bit-by-bit, transfer.
Figure 6-4 Bit-Field Packing in Big-Endian and Little-Endian Formats A | A | A | A | A | A | A | B | B | B | B | B | B | B | B | B | B | C | C | C | D | D | E | E | E | E | E | E | E | E | E | X |
6 | 5 | 4 | 3 | 2 | 1 | 0 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 2 | 1 | 0 | 1 | 0 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | X |
A | A | A | A | A | A | A | B | B | B | B | B | B | B | B | B | B | C | C | C | D | D | E | E | E | E | E | E | E | E | E | X |
6 | 5 | 4 | 3 | 2 | 1 | 0 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 2 | 1 | 0 | 1 | 0 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | X |
X | E | E | E | E | E | E | E | E | E | D | D | C | C | C | B | B | B | B | B | B | B | B | B | B | A | A | A | A | A | A | A |
X | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 1 | 0 | 2 | 1 | 0 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
B | A | A | A | A | A | A | A | B | B | B | B | B | B | B | B | E | E | D | D | C | C | C | B | X | E | E | E | E | E | E | E |
0 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 1 | 0 | 1 | 0 | 2 | 1 | 0 | 9 | X | 8 | 7 | 6 | 5 | 4 | 3 | 2 |
LEGEND: X = not used, MS = most significant, LS = least significant |