Bit fields in C are members of a structure that occupy a specified number of bits instead of the standard size of the type. They help save memory, especially for storing flags and compact sets of states.
Declaration:
struct Flags { unsigned int enable : 1; unsigned int mode : 2; unsigned int code : 5; };
In this example, the structure occupies a minimum of 8 bits, rather than 3 * sizeof(unsigned int).
Where to apply:
Limitations and pitfalls:
Example:
struct Packet { unsigned char start : 1; unsigned char id : 3; unsigned char flag : 4; };
Question: Can you use char or signed int types for bit fields?
Answer: The C standard allows using int, unsigned int, and (according to compiler extensions) other standard integer types (char, short). However, portability is guaranteed only for int and unsigned int.
Example of error:
struct Example { signed char a : 3; }; // Different compilers/architectures may have different rules for sign storage and bit order.
Story
When integrating software on ARM and x86, it became clear that a structure with bit fields unpacked differently: various bit order and alignment. The design did not account for these differences, leading to an inability to read data in a cross-platform environment.
Story
In the motor controller management system, the
chartype was mistakenly used in bit field structures. On some ARM processors, this resulted in incorrect sign extension, leading to erroneous flag processing.
Story
In a network protocol, bit fields were used to pack message flags; it was not noted that higher uninitialized fields remain junk. When transmitting between devices, random state errors occurred due to differences in initialization.