Search code examples
c++structsizeofpacking

C/C++ struct packing not working


I'm trying to pack a struct, using g++ on 64-bit 32-bit windows.

struct Foo
{
    uint8_t a;
    uint32_t b;
} __attribute__((packed));


int main(int argc, char *argv[])
{
    qDebug() << "sizeof(Foo):" << sizeof(Foo);
    return 0;
}

This outputs 8. Other things I've tried:

{ uint8_t a; } // Gives 1, correct.
{ uint8_t a; float b; } // Gives 8, expected 5.
{ uint8_t a; uint16_t b; } // Gives 4, expected 3.
{ uint16_t a; uint8_t b; uint8_t c; } // Gives 4, correct.

So it seems like the struct is packed, but sizeof is rounded up in some cases? (Actually after having written this question I think I can answer it, but I'll post it anyway for posterity.)

Edit: Actually I have no idea. I thought aligned(1) would fix it but it doesn't.


Solution

  • Finally found it is a bug in g++.

    The general issue is that the attribute ((__packed)) applies only to last field of struct. This is the cause for the size of 9. Trick is here '#pragma pack(1)'. By it you get expected sizes. The issue is that this field-alignment gets applied even for struct/union's marked to be packed (or via -fpack-struct option).

    Well there seems to be some doubt of that explanation, but the solution works - use #pragma pack(1) instead like this:

    #pragma pack(1)
    
    struct Foo
    {
        uint8_t a;
        uint32_t b;
    };
    
    #pragma pack()
    

    The second #pragma resets the pack value.