Representation of individual bits in C

If I have 16 bits that represent 3 pairs of values, each of 5 bits and another 1-bit value in that order, can a bit field be used to describe this? Is ANSI C a guarantee that the bit will be exactly in the order I specify?

struct { unsigned v1 : 5; unsigned v2 : 5; unsigned v3 : 5; unsigned v4 : 1; } test; 

If not, is there any other data structure that I can use to represent this? Or should I just save two 8-bit char and programmatically simulate them to be sure of portability?

+1
source share
3 answers

The relevant quote I can find is 6.7.2.1 (1), from C99:

An implementation can allocate any addressable storage unit that is large enough to store a bit field. If enough space remains, the bit field that immediately follows the other bit field in the structure should be packed into adjacent bits of the same block. If there is not enough space, then whether a bit field that does not fit will fit in the next block or overlap adjacent units is determined by the implementation. The order of distribution of bit fields within a unit (from high order to low or low order) is determined by the implementation. The alignment of the storage address block is not indicated.

I think unsigned is not really a type of base unit, but rather is only part of the bitfield declaration itself: T : n means "take n bits of type T ". The real question is whether an implementation is required to select a "large" unit. For example, it can use three bytes, making a char block; one for v1 , one for v2 , and the last for v3, v4 . Or it can make the device a 16-bit integer, in which case you only need to use one unit.

However, as you noted, the ordering of bit fields within the device is not defined. The atomic unit of data in C is an address, and bit fields have no addresses. He guaranteed that the address of members of the structure increases in the order of their declaration, but you cannot draw such a conclusion about bit fields (only about their basic units).

+4
source

You can use the uint16_t type from stdint.h , which is guaranteed to be a type synonym for an unsigned 16-bit quantity. If a statement worries you, it becomes more complex.

+1
source

In addition to the implementation-specific bit-bits, you may also need to add a pragma or other compiler directive to tell the compiler not to insert any pad bits.

Here is the answer I just wrote about how to use bit fields to extract some bits from a byte value. When I wrote this, I found that I needed to add #pragma pack(1) , otherwise my bit fields would not fit in one byte.

Access bits in char in C

This answer also shows how to use union to access data in the form of a complete byte or bit fields. You can use the same method to access data as a short integer or as bit fields.

0
source

Source: https://habr.com/ru/post/1500876/


All Articles