Side assignment of the structure of bit fields

I do not know why, but the assignment of bit fields does not work as expected. This is probably just stupid, but I could not find the problem.

Any help is more than welcome.

typedef struct a { unsigned char a1 :1; unsigned char a2 :3; unsigned char a3 :2; unsigned char a4 :2; } __attribute__((packed)) mystruct; int main() { mystruct d; d.a1 = 0; d.a2 = 2; d.a3 = 1; d.a4 = 2; unsigned char *val = (unsigned char*) &d; printf("%02X \n", *val); printf("%02X \n", sizeof(hola)); exit(0); } 

returned output:

 94 01 

expected output:

 26 01 
+2
source share
2 answers

Almost everything about bit fields is determined by the implementation. And, in particular, the order of bits in a block.

(C99, 6.7.2.1p10) "The order of the distribution of bit fields within a block (from high order to low or low order) is determined by the implementation."

In your implementation, the bits are first stored in units of lsb (the least significant bit), not msb (the most significant bit), as you expected.

What do you have:

 [a1.0] [a2.0] [a2.1] [a2.2] [a2.0] [a3.1] [a4.0] [a4.1] 0 0 1 0 1 0 0 1 bit 0 - bit 7 lsb - msb 

which is 0x94 if you think the most significant bit is the least significant.

+8
source

ASCII art:

  MSB LSB +----+----+----+----+----+----+----+----+ |a4.1|a4.0|a3.1|a3.0|a2.2|a2.1|a2.0| a1 | +----+----+----+----+----+----+----+----+ | 1 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | +----+----+----+----+----+----+----+----+ | 0x9 | 0x4 | +----+----+----+----+----+----+----+----+ 

As noted, behavior is determined by implementation; this is one of two legitimate ways to organize data and, apparently, the format chosen on your computer. Alternative behavior.

  MSB LSB +----+----+----+----+----+----+----+----+ | a1 |a2.2|a2.1|a2.0|a3.1|a3.0|a4.1|a4.0| +----+----+----+----+----+----+----+----+ | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | +----+----+----+----+----+----+----+----+ | 0x2 | 0x6 | +----+----+----+----+----+----+----+----+ 

This was apparently the behavior you were expecting.

Since this is a specific implementation, you can look in the manual and find out what your compiler does, because the compiler must document its behavior.

If you have portability to worry about, you need to think about how you organize your structure definitions in order to work the way you need to work on every platform you use.

+8
source

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


All Articles