The main goal of bit fields is to provide a way to store memory in arrays with an aggregate set of data, creating a more dense data packing.
The whole idea is to take advantage of situations in which you have several fields in some type of structure that don't need the full width (and range) of some standard data type. This gives you the opportunity to pack several of these fields into one distribution unit, thereby reducing the overall size of the structure type. And an extreme example can be logical fields, which can be represented by individual bits (for example, 32 of them can be packed into a single block allocation unsigned int ).
Obviously, this only makes sense in a situation where the pluses of consuming reduced memory outweigh the minuses of slow access to values stored in bit fields. However, such situations arise quite often, which makes bit-fields absolutely irreplaceable language features. This should answer your question about the modern use of bit fields: they are not only used, but are practically mandatory in any practically significant code oriented to processing large volumes of homogeneous data (for example, on large graphs, for example, by their example) - advantages Uses far outweigh any individual performance penalties.
In a sense, bit fields in their purpose are very similar to such "small" arithmetic types: signed/unsigned char , short , float . The actual data processing code usually does not use any types smaller than int or double (with a few exceptions). Arithmetic types of type signed/unsigned char , short , float exist only to serve as types of "storage": as compact elements with storage of structure types in situations where it is known that their range (or accuracy) is sufficient. Bit fields are another step in the same direction that brings better performance for the much greater benefits of memory savings.
So, this gives us a fairly clear-cut set of conditions under which it is worth using bit fields:
- A structure type contains several fields that can be packed into fewer bits.
- The program creates an instance of a large number of objects of this type of structure.
If the conditions are met, you declare all the bit packets of the fields adjacent (usually at the end of the structure type), assigning them the appropriate bit width (and usually take some steps to ensure that the bit width is appropriate). In most cases, it makes sense to play with ordering these fields to achieve the best packaging and / or performance.
There is also a strange secondary use of bit fields: using them to display groups of bits in various external representations, such as hardware registers, floating point formats, file formats, etc. It was never intended for the correct use of the bit field, although for some inexplicable reason this kind of abuse of the bit field continues to appear in real code. Just don't do it.