简体   繁体   中英

Size of structure which contains bitfields is different on different compiler

I ran the below program on VS and on GCC.

#include <stdio.h>

int main(void)
{
    struct bitfield
    {
        unsigned a : 3;
        char b;
        unsigned c : 5;
        int d;
    }bit;

    printf("Size = %d\n", sizeof(bit));

    return 0;
}

To my surprise, VS gives 16 as the sizeof structure and GCC gives 12.

My understanding is that the compiler tries to allocate a , char b and c in 1 row (Bank0, Bank1, Bank2, Bank3) and the int d in another row. This seems to suggest that the size of the structure should be 8 bytes (Assuming 32bit system).

Can anyone explain these results? I am running on a 64-bit machine.

The compiler is only required to pack bit fields that are declared adjacently in the struct into the same "addressable storage unit" (which is probably a chunk of 32 bits in this case, given 32 bit CPU). You showed a char in between them, so the compiler is free to allocate your struct as it pleases.

Generally, bit fields are incredibly poorly specified by the standard and therefore completely non-portable and unpredictable. The order of allocation of bits is not specified. It is not specified which bit that is the MSB. Alignment is not specified. It is not specified if the bit fields may or may not "straddle" a "storage unit". And so on.

Furthermore, a struct may contain padding bytes anywhere.

A better idea is to never use bit fields at all, but to use the bitwise operators instead.

Since your system has 64-bit architecture, most compilers would pad in 8-bytes.
Gcc in its present version still pads 4 bytes.
Also, structure padding is totally compiler dependent. There are many undefined behaviors which you would see in 'c' codes, like using unary increment (pre/post), padding, memory map, etc which is totally compiler and m/c dependent. So, there is actually no explanation as such.
Also, run the following code on your system. VS should o/p 24 and GCC 16 in this case.

#include <stdio.h>

int main(void)
{
    struct bitfield
    {
        unsigned a : 3;
        unsigned c : 5;
        int d;
        char b;
    }bit;

    printf("Size = %d\n", sizeof(bit));

    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM