Bits in C

Bit operations

Bit fields

It is possible to to place several fields of a structure within a single integer. This can be done to conserve storage (though at the cost of increased runtime) or to conform to external standards.

IP (Internet Protocol) packet header

The first four bits of an IPv4 packet contains the IP version of the packet (which is 4 for 99.9% of the packets) and the next four bits contain the length of the header in 32 bit words. Because these must be packed in big endian order on the "wire", the standard ip.h include file, must contain a pre-processor conditional. This example is copyrighted by the Free Software Foundation.

#if __BYTE_ORDER == __LITTLE_ENDIAN
    unsigned int flags:4;
    unsigned int overflow:4;
#elif __BYTE_ORDER == __BIG_ENDIAN
    unsigned int overflow:4;
    unsigned int flags:4;
#else
# error	"Please fix <bits/endian.h>"
#endif

Syntax of the bit field specification

The type of the bit field can be either unsigned int, signed int, or int. Oddly enough, plain int's may be considered signed or unsigned depending on the implementation. Because older C implementations considered all bit fields to be unsigned, it is safer to stick with unsigned int.

The field name can be omitted. This is useful when the programmer wishes to align following fields in a special manner, perhaps to conform with an external standard.

The fields are allocated within integers from left-to-right or right-to-left depending on the endianness of the implementation. If a field "straddles" an integer boundary, it is usually placed in the next integer. However, this is also implementation dependent. Finally, since the size of the integer is implementation dependent, it may be difficult to predict when the straddle occurs.

As a special case, if the field width is 0, the next bit field is placed at the beginning of the next integer.

One consequence of these rules is that it is difficult to write portable C code using bit fields. If you do, stick to unsigned integer fields and use 0 field widths liberally to obtain the desired alignment. Bit fields may seem more convenient than masking and shifting with bit operations, but the convenience comes at the price of portability.

Other restrictions on bit fields

Bit fields cannot be used as arrays.

Bit fields do not have addresses. The & operator cannot be applied to a bit field.