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 that is 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 that are 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. The C
and D compilers attempt to pack bits as efficiently as possible,
but they are free to do so in any order or fashion they desire.
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 by 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 cannot 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 by using the
&
operator.