I've been doing some reading about bitfields in C, how the C standard doesn't enforce any particular ordering of the fields in a machine word, and so on.
I hope this question appropriately fits the format of SO.
My question is whether my struct (definition following) will actually perform in the way I expect. Here's the definition I came up with, and then I'll discuss what I want:
typedef enum {
STATE_ONE,
STATE_TWO,
STATE_THREE,
STATE_FOUR
} __attribute__ ((packed)) State;
typedef struct MyStruct {
// One of State enum (maximum of 4 states).
unsigned state : 2;
// Remaining 30 bits are used differently depending on 'state'.
union {
// If 'state' is STATE_ONE (0), the remaining bits are an ID number.
unsigned id : 30;
/*
* For all other states, the remaining bits are the 2-tuple:
* (buffer A index, buffer B index).
*/
struct {
unsigned bufferAIdx : 16;
unsigned bufferBIdx : 14;
} __attribute__ ((packed)) index;
} __attribute__ ((packed));
} __attribute__ ((packed)) MyStruct;
(This is for gcc, thus the __attribute__
directives).
You can probably tell what I'm going for: depending on the value of the 'state' field I want to use the remaining 30 bits for different purposes. They should either be an ID number, or a 2-tuple of indices into various buffers. And, each instance of MyStruct should fit into a maximum of 5 bytes.
So what I want to be able to do is something to this effect:
MyStruct a, b;
a.state = STATE_ONE;
a.id = 123456;
b.state = STATE_THREE;
b.index.bufferAIdx = 6;
b.index.bufferBIdx = 2;
Mainly I'm looking for input on whether this is "the right thing" to do. In other words, am I misusing the ideas of bitfields/unions here? If you were going to be a maintainer of this code, would you cringe in horror upon seeing this? Or, would you prefer to see the whole data object stored in a uint32_t
type and manipulated via masking and shifting?