简体   繁体   中英

output of the structure size using bitfields

#pragma pack(2)
struct a{
  unsigned a:1;
  unsigned b:1;
  int c;
  unsigned d:4;
  unsigned :4;
  unsigned e:1;
  unsigned :0;
  unsigned f:1;} ;

int main()
{
    printf("%d",sizeof(struct a));
}

The output of the following program comes to be 16 when pragma pack is not used but is 10 when pragma pack is used.please explain how is this?

First, #pragma s are compiler-specific so without you specifying your compiler and CPU (and perhaps compiler version and commandline options) we can only speculate.

But, a plausible explanation is that, for the "pack(2)" version:

#pragma pack(2)
struct a{ 
    unsigned a:1;    // at byte offset 0, could be least- or most-significant bit
    unsigned b:1;    // also in byte 0, besides a
    int c;           // explicitly requested this int be mis-aligned at byte 2
                     //   seems you've 32-bit ints, so 4-byte are 2,3,4,5
    unsigned d:4;    // at byte 6
    unsigned :4;     // also fits in byte 6
    unsigned e:1;    // in byte 7
    unsigned :0;     // requests following field be aligned for unsigned type
                     //   your unsigned int must be 32-bits, so this means
                     //   following field must start at 0, 4, 8, 12 etc.
                     //   so: skips rest of byte 7 and moves to 8
    unsigned f:1;    // occupies one bit of byte 8
};

Because the packing is "2", and already using the 9 bytes from [0] to [8], the sizeof(a) is rounded up to 10.

Without your pragma the default would be 4 bytes / 32-bits. So, the first int is aligned on a 32-bit address for faster access, skipping 2 and 3 and occupying bytes 4, 5, 6, 7. That pushes e along by those 2 skipped byte into in byte 9, and :0 forces the following field to be in byte 12. The total size is then rounded to the 32-bit word size, so from 13 (for bytes [0] to [12]), up to 16.

The effect of #pragma pack(2) is purely implementation defined, so you really should read the documentation about it (but I can sort of guess). Without the pragma, according to the standard, the presence of a non-bitfield element or a bitfield with size 0 causes the compiler to advance to the next "unit", so in your structure, a and b are in the first unit, c in the second, d and e in the third, and f in the fourth. Given that the size is 16, I'd guess 4 byte units (which is almost universal today). With #pragma pack(2) , I'd guess that the basic unit is two bytes, rather than four. And that this doesn't change the size of an int , so c remains four bytes, but the other units above are only two. Which gives a total of ten bytes, so my guess probably isn't too far off.

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