VStudio c++ alignment of bitfield in union

219 views Asked by At

In VStudio 2010, I'm trying to create a union to access a 2-byte value conveniently:

#pragma pack(push,1) // disable padding
typedef struct {
    uint8_t r:3;
    uint8_t g:3;
    uint8_t b:3;
}tsRgb;

typedef union {
    uint16_t raw;
    tsRgb rgb; 
}tPixelData;
#pragma pack(pop)

int main(){
    tPixelData pixel;
    pixel.raw = 0xABE5;
    return 0;
}

I'm expecting to see pixel.r = 5, pixel.g = 4, pixel.b = 7. the r and g are ok, but the b is 3.

What am I doing wrong? I assume I'm not alligning the bits correctly?

2

There are 2 answers

2
Bo Persson On BEST ANSWER

The third field will be in a separate byte.

In VC++ the bitfields do not cross the boundaries of the underlying type. When you have used 3+3 bits there are only 2 left, so the next field will use 3 bits from a fresh byte.

It might work better if you use uint16_t instead of uint8_t.

"Disable padding" works on the byte level, not on the bit level.

1
Andrew Henle On

Using bit-fields is as you want to is fundamentally problematic. Per the C Standard, 6.7.2.1 Structure and union specifiers, paragraph 11 (since your question is also tagged C):

An implementation may allocate any addressable storage unit large enough to hold a bit- field. If enough space remains, a bit-field that immediately follows another bit-field in a structure shall be packed into adjacent bits of the same unit. If insufficient space remains, whether a bit-field that does not fit is put into the next unit or overlaps adjacent units is implementation-defined. The order of allocation of bit-fields within a unit (high-order to low-order or low-order to high-order) is implementation-defined. The alignment of the addressable storage unit is unspecified.

The layout and alignment of the bits in a bit-field are all implementation-defined. Fields may or may not cross storage unit boundaries, they may be stored in any order.

They're not portable at all.