Patsy7z7
Patsy7z7

Reputation: 103

C++ Bitfield Struct size definition (Why is it packed larger?)

I have a question about bit packing in C++.

Lets say we have a struct defined in C++. Here it is below:

typedef struct
{
    unsigned long byte_half : 4;             //0.5
    unsigned long byte_oneAndHalf : 12;      //2
    union
    {
        unsigned long byte_union_one_1 : 8;  //3
        unsigned long byte_union_one_2 : 8;  //3
        unsigned long byte_union_one_3 : 8;  //3
    };
    unsigned long byte_one        : 8;       //4
}LongStruct;

It is a struct called LongStruct. From the looks of it, it occupies 4 bytes, and fits into a long. Now I execute the following line:

int size = sizeof(LongStruct);

I take a look at size, expecting it to have the value 4. Turns out I get 12 instead. In what way am I incorrectly visualizing my struct?

Thank you in advance for any help you can give me.

Upvotes: 1

Views: 498

Answers (2)

barak manos
barak manos

Reputation: 30126

The union is expanded to a long, so its size is 4 bytes instead of 1 byte.

As a result, it is aligned to a 4-byte offset from the beginning of the structure.

In addition, the entire structure is expanded to be a multiple of 4 bytes in size.

So the actual structure looks like this:

unsigned long byte_half       :  4; // bits  0 -  3
unsigned long byte_oneAndHalf : 12; // bits  4 - 15
unsigned long byte_padding_1  : 16; // bits 16 - 31 // align union

union
{
    unsigned long byte_union_one_1 :  8; // bits 32 - 39
    unsigned long byte_union_one_2 :  8; // bits 32 - 39
    unsigned long byte_union_one_3 :  8; // bits 32 - 39
    unsigned long byte_padding_2   : 24; // bits 40 - 63 // expand union
};

unsigned long byte_one       :  8; // bits 64 - 71
unsigned long byte_padding_3 : 24; // bits 72 - 95 // expand structure

Hence the total size is 96 bits (12 bytes).

Upvotes: 3

Mark B
Mark B

Reputation: 96233

The anonymous union is not substituting its attributes, but is taking a four-byte chunk in the middle of your bit field struct. So your first two members are two bytes + two padding. Then your union is one byte plus three padding. Then your final member is one byte and three more padding. The total is the 12 you observe.

I'll try to dig into the standard to see exactly what it says about anonymous union bitfields. Alternately if you describe the real problem you're trying to solve we could look into answering that as well.

As an aside you have this tagged C++ so strongly prefer struct X {}; over typedef struct {} X;

Upvotes: 3

Related Questions