Will this bitfield work as I expect?

I read about bit fields in C, as the C standard does not apply any particular field order in machine words, etc.

I hope this question will suit the SO format accordingly.

My question is whether my structure (definition) will actually perform as I expect. Here is the definition that I came up with and then I will 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, so the __attribute__ directive).

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 must be either an identification number or a 2x index into various buffers. And each instance of MyStruct should fit in a maximum of 5 bytes.

So I want to be able to do this:

 MyStruct a, b; a.state = STATE_ONE; a.id = 123456; b.state = STATE_THREE; b.index.bufferAIdx = 6; b.index.bufferBIdx = 2; 

Basically I am looking for information on whether this is necessary "correctly." In other words, am I abusing the ideas of beatpots / unions here? If you were going to be a supporter of this code, would you cringe in horror when you saw this? Or would you rather see the entire data object stored in the uint32_t type and manipulate it with masking and offset?

+4
source share
1 answer

When the beginning of any union or struct is aligned, you cannot put all your data in 32 bits this way. You should encapsulate your union and struct reverse, as follows (attributes removed for readability):

 typedef struct MyStruct { union { struct { unsigned state : 2; unsigned id : 30; } struct { unsigned /* unused */ : 2; unsigned bufferAIdx : 16; unsigned bufferBIdx : 14; }; }; }; 
+4
source

All Articles