c++ - How does compiler determine the size of a bitfield struct? -
for example:
struct { uint32_t forecolor_ : 32; uint32_t backcolor_ : 32; uint16_t lfheight_ : 16; uint16_t flags_: 4; bool lfbold_: 1; bool lfitalic_: 1; bool lfunderline_: 1; bool lfdashline_: 1; bool lfstrike_: 1; bool lfsubscript_: 1; bool lfsuperscript_: 1; };
is 16 bytes but
struct { uint32_t forecolor_ : 32; uint32_t backcolor_ : 32; uint16_t lfheight_ : 16; uint8_t flags_: 4; bool lfbold_: 1; bool lfitalic_: 1; bool lfunderline_: 1; bool lfdashline_: 1; //for ime bool lfstrike_: 1; bool lfsubscript_: 1; bool lfsuperscript_: 1; };
is 12 bytes long.
i thought flags_ should have same length, seems not.
why?
the standard (9.6 of the working draft) says this:
specifies bit-field; length set off bit-field name colon. bit-field attribute not part of type of class member. constant-expression shall integral constant-expression value greater or equal zero. constant-expression may larger number of bits in object representation ( 3.9 ) of bit-field’s type; in such cases bits used padding bits , not participate in value representation ( 3.9 ) of bit-field. allocation of bit-fields within class object implementation-defined. alignment of bit-fields implementation-defined. bit-fields packed addressable allocation unit. [ note: bit-fields straddle allocation units on machines , not on others. bit-fields assigned right-to-left on machines, left-to-right on others. —end note]
(my emphasis)
so depend on compiler. appears happening in case - , describe normal behaviour - is combining bitfields of same type , packing structure 4 byte boundary, in first case have:
struct { uint32_t forecolor_ : 32; // 4 bytes (total) uint32_t backcolor_ : 32; // 8 bytes uint16_t lfheight_ : 16; // 10 bytes uint16_t flags_: 4; // 12 bytes bool lfbold_: 1; // 13 bytes bool lfitalic_: 1; bool lfunderline_: 1; bool lfdashline_: 1; bool lfstrike_: 1; bool lfsubscript_: 1; bool lfsuperscript_: 1; // still 13 bytes };
which padded 16 bytes, , in second have:
struct { uint32_t forecolor_ : 32; // 4 bytes (total) uint32_t backcolor_ : 32; // 8 bytes uint16_t lfheight_ : 16; // 10 bytes uint8_t flags_: 4; // 11 bytes bool lfbold_: 1; // 12 bytes bool lfitalic_: 1; bool lfunderline_: 1; bool lfdashline_: 1; bool lfstrike_: 1; bool lfsubscript_: 1; bool lfsuperscript_: 1; // still 12 bytes };
which needs no padding , stays @ 12 bytes.
Comments
Post a Comment