Bit-fields give an ability to declare structure fields that are smaller than the character width. Bit-fields are implemented with byte-level or word-level mask. The following example results in a structure of 8 bytes.
struct C
{
short s; /* 2 bytes */
char c; /* 1 byte */
int bit1 : 1; /* 1 bit */
int nib : 4; /* 4 bits padded up to boundary of 8 bits. Thus 3 bits are padded */
int sept : 7; /* 7 Bits septet, padded up to boundary of 32 bits. */
};
The comments describe one possible layout, but because the standard says the alignment of the addressable storage unit is unspecified, other layouts are also possible.
An unnamed bit-field may be of any size, but they can't be initialized or referenced.
A zero-width bit-field cannot be given a name and aligns the next field to the boundary defined by the datatype of the bit-field. This is achieved by padding bits between the bit-fields.
The size of structure 'A' is 1 byte.
struct A
{
unsigned char c1 : 3;
unsigned char c2 : 4;
unsigned char c3 : 1;
};
In structure B, the first unnamed bit-field skips 2 bits; the zero width bit-field after c2
causes c3
to start from the char boundary (so 3 bits are skipped between c2
and c3
. There are 3 padding bits after c4
. Thus the size of the structure is 2 bytes.
struct B
{
unsigned char c1 : 1;
unsigned char : 2; /* Skips 2 bits in the layout */
unsigned char c2 : 2;
unsigned char : 0; /* Causes padding up to next container boundary */
unsigned char c3 : 4;
unsigned char c4 : 1;
};