#gcc/g++ bitfields produce wrong size

1 messages · Page 1 of 1 (latest)

summer talon
#

compilling this code with gcc/g++ gives error stating that size of u is 9

#

mingw64

summer talon
#

dont know why i didnt narrow it down before but this is just bitfields

#

gcc/g++ bitfields produce wrong size

slender ibex
# summer talon dont know why i didnt narrow it down before but this is just bitfields

This particular example does not seem to produce sizeof(u) == 8 on any actual compiler 🤷

I tested the following code on https://godbolt.org/ (it can be compiled both as C and C++):

#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>

struct u {
    bool c : 1;
    bool d : 1;
    bool e : 1;
    uint64_t f : 2;
} __attribute__((packed));

size_t test(void) {
    return sizeof(struct u);
}

Most GCC and clang versions consider sizeof(struct u) to be 1; even some more obscure compilers like icc, icx and zig c++ give the same result. The major exceptions are MinGW GCC (all available versions give 9) and MinGW clang (all available versions give 16).

Technically the bit field packing is implementation defined, and GCC documents many of those details as “determined by ABI”; the fact that __attribute__((packed)) is a GCC extension also complicates things (because the code cannot be compiled under MSVC to test its behavior).

#

Although it is possible to use pragmas which are supported by MSVC instead of __attribute__((packed)):

#pragma pack(1)
struct u {
    bool c : 1;
    bool d : 1;
    bool e : 1;
    uint64_t f : 2;
};
#pragma pack()

In this case the behavior of MSVC, MinGW GCC and MinGW clang becomes the same — sizeof(struct u) == 9. So apparently the difference is that in the Windows ABI for a packed struct the bool and uint64_t bit fields don't get packed together, and the uint64_t bit field always occupies the full uint64_t size, even though that leaves some bytes completely unused.

#

And also MinGW clang looks buggy (it accepts the packed attribute used by GCC, but does not produce the same result as GCC for the same platform).

summer talon
slender ibex
#

Usually bit fields with a different base type don't get packed together, but apparently the bool case may be handled specially in some cases.

#

The packed attribute removes some of those “different base type” restrictions on many platforms, but apparently not on Windows.

summer talon
#

ok thanks👍 what i am trying to compile is freestanding x86_64. is there maybe a way to tell mingw gcc not to use windows ABI?

#

-mabi=sysv -mno-ms-bitfields
got it

#

👍