Tamas Karpati
Tamas Karpati

Reputation: 13

How to pack a struct tightly on Windows?

I'm trying to create a packed struct which represents a header of a specific data packet. Because of this, it must not have any padding to match the size given in the specification. However, on Windows, it will have a 1 Byte padding after the last field, no matter how I tell the compiler to tightly pack the structure.

I have tried this code on Compiler Explorer and on most of the platforms I get the result I wanted, except for MSVC. I also tried on Windows Subsystem for Linux (WSL) with GCC which again gives me a proper result. I only got padding issues on Windows.

The simplified version of the stucture looks like this:

typedef struct
{
    unsigned a : 10;
    unsigned b : 1;
    unsigned c : 5;
    unsigned d : 8;
} __attribute__((packed)) A;

Using MSVC:

#pragma pack(push, 1)
typedef struct
{
    unsigned a : 10;
    unsigned b : 1;
    unsigned c : 5;
    unsigned d : 8;
} A;
#pragma pack(pop)

In case of MSVC I also tried to add the /Zp1 compiler parameter to default to 1 Byte alignment.

I expect the size of the structure to be 3 Bytes. On Linux with gcc or clang it's okay, but on Windows with MinGW GCC or MSVC, the size is always 4 Bytes.

Upvotes: 1

Views: 2407

Answers (1)

user555045
user555045

Reputation: 64904

If you change the types to this:

#pragma pack(push, 1)
typedef struct
{
    unsigned short a : 10;
    unsigned short b : 1;
    unsigned short c : 5;
    unsigned char d : 8;
} A;
#pragma pack(pop)

Then it does come out as 3 bytes.

You could also emulate the bitfields manually, to minimize such surprises.

Upvotes: 2

Related Questions