I have a union that looks similar to the following:
typedef
union _thing
{
struct thing_indiv {
uint16_t one:5;
uint16_t two:4;
uint16_t three:5;
uint16_t four:5;
uint16_t five:6;
uint16_t six:6;
uint16_t seven:6;
uint16_t eight:7;
uint16_t nine:4;
uint16_t ten:5;
uint16_t eleven:6;
uint16_t twelve:5;
uint16_t thirteen:5;
uint16_t fourteen:4;
uint16_t fifteen:2;
uint16_t unused:5;
} __attribute__((packed)) thing_split;
uint8_t thing_comb[10];
} thing;
But it doesn't behave how I expect. I want to assign bytes to thing.thing_comb
and retrieve the relevant items from thing.thing_split
.
For example, if thing_comb = { 0xD6, 0x27, 0xAD, 0xB6. ..}
I would expect thing.thing_split.one to contain 0x1A
(the 5 most significant bits of 0xD6
, but it does not, it contains 0x16
, the 5 least significant bits. I declared each of the fields as uint16_t
to keep gcc from complaining about crossing byte boundaries (I experience the same behavior with uint8_t
).
Is there a way to lay out this struct to obtain this behavior?