The example you quoted is being used to explain that multiple bit-fields are usually (not necessarily) packed together. If you look at it more carefully:
// 3 bits: value of b1 - 3 bits occupied
// 2 bits: unused - 2 bits left unused
// 6 bits: value of b2 - 6 bits occupied (these 6 can't fit into the previous byte
as 5 bits are already occupied. What will happen in this
case? Will these 6 bits go into the next byte? Will they
somehow *overlap* two bytes?
// 2 bits: value of b3
// 3 bits: unused
If the result of sizeof(S) == 2
is true, then we can say that the field b2
is straddling bytes. The example is trying to explain this concept.
The example is not so clear at explaining this, so let me create a slightly better one:
struct S {
unsigned char b1 : 3, : 2, b2 : 6, b3 : 3;
};
The difference is b3
is now 3 bits. Total bits of the struct = 3 + 2 + 6 + 3 = 14
. If I print the sizeof (S)
now, I get, 3
as output which tells me there is no byte straddling on my system.
Furthermore, You can find this at the bottom of the page:
- Everything about the actual allocation details of bit fields within the class object
- For example, on some platforms, bit fields don't straddle bytes, on others they do
- Also, on some platforms, bit fields are packed left-to-right, on others right-to-left
Could anyone explain me if (if I am not wrong) this bit fields actually change the size of the variable or they are just a "suggestion" for the compiler? (as inline keyword). If bit fields works as I understand, you would be able to stor a boolean on 1 bit (which is not possible because the memory is splitted on chunks of 1 bytes)
Almost everything about bit-fields is implementation defined so to get the correct answers you will have to look at each compiler's documentation and read the ABI documents to get the answer. For example, this is from GCC docs:
Whether a bit-field can straddle a storage-unit boundary (C90 6.5.2.1, C99 and C11 6.7.2.1).
Determined by ABI.
If we look at the assembly generated for GCC 10.1, we can see that the bit-fields are actually being used:
# b1: 1, b2: 61, b3: 3
sub rsp, 24
mov eax, -767
lea rdi, [rsp+14]
mov WORD PTR [rsp+14], ax
The number -767
in binary:
b3 b6 b1
11 111101 00000001
boolean on 1 bit
The answer would not be complete without mentioning std::vector<bool>
which tried to do this, but it turned out that it was not such a great idea.