Bit Fields

D also permits the definition of integer struct and union members of arbitrary numbers of bits, known as bit fields. A bit field is declared by specifying a signed or unsigned integer base type, a member name, and a suffix indicating the number of bits to be assigned for the field, as shown in the following example:

struct s {
        int a : 1;
        int b : 3;
        int c : 12;
};

The bit field width is an integer constant separated from the member name by a trailing colon. The bit field width must be positive and must be of a number of bits not larger than the width of the corresponding integer base type. Bit fields larger than 64 bits may not be declared in D. D bit fields provide compatibility with and access to the corresponding ANSI-C capability. Bit fields are typically used in situations when memory storage is at a premium or when a struct layout must match a hardware register layout.

A bit field is a compiler construct that automates the layout of an integer and a set of masks to extract the member values. The same result can be achieved by simply defining the masks yourself and using the & operator. C and D compliers try to pack bits efficiently The compliers do not follow any order while packing the bits. Therefore, bit fields are not guaranteed to produce identical bit layouts across differing compilers or architectures. If you require stable bit layout, you should construct the bit masks yourself and extract the values using the & operator.

A bit field member is accessed by simply specifying its name in combination with the "." or -> operators like any other struct or union member. The bit field is automatically promoted to the next largest integer type for use in any expressions. Because bit field storage may not be aligned on a byte boundary or be a round number of bytes in size, you may not apply the sizeof or offsetof operators to a bit field member. The D compiler also prohibits you from taking the address of a bit field member using the & operator.