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.
精彩评论