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.
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
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.
Bit fields cannot be used as arrays.
Bit fields do not have addresses. The &
operator cannot be applied to a bit field.