For example:
struct a {
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 a {
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 the same length, but it seems not.
Why?
In above student structure size of the structure without bit field is size of (StdId) + size of (Age) = 8 bytes + 8 Bytes = 16 bytes. After using bit fields to its members, it is 8 bits + 4 bits = 12 bits = 1.5 bytes which is very much less. Hence we can save lot of memory.
A bit field is a data structure that consists of one or more adjacent bits which have been allocated for specific purposes, so that any single bit or group of bits within the structure can be set or inspected.
In programming terminology, a bit field is a data structure that allows the programmer to allocate memory to structures and unions in bits in order to utilize computer memory in an efficient manner.
Disadvantages of bit-fields We cannot take address of a bit-field. Bit-fields cannot be made arrays. Size of bit-fields cannot be taken (using sizeof() operator). Bit fields cannot be pointers.
The standard (9.6 of the working draft) says this:
specifies a bit-field; its length is set off from the bit-field name by a colon. The bit-field attribute is not part of the type of the class member. The constant-expression shall be an integral constant-expression with a value greater than or equal to zero. The constant-expression may be larger than the number of bits in the object representation ( 3.9 ) of the bit-field’s type; in such cases the extra bits are used as padding bits and do not participate in the value representation ( 3.9 ) of the bit-field. Allocation of bit-fields within a class object is implementation-defined. Alignment of bit-fields is implementation-defined. Bit-fields are packed into some addressable allocation unit. [ Note: bit-fields straddle allocation units on some machines and not on others. Bit-fields are assigned right-to-left on some machines, left-to-right on others. —end note]
(my emphasis)
So it will depend on your compiler. What appears to be happening in your case - and I would describe as fairly normal behaviour - is that it is only combining bitfields of the same type and then is packing the structure to a 4 byte boundary, so in the first case we have:
struct a {
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 is then padded to 16 bytes, and in the second we have:
struct a {
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 and stays at 12 bytes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With