```cpp #include #include #include struct S { // will usually occupy 2 bytes: unsigned char b1 : 3; // 1st 3 bits (in 1st byte) are b1 unsigned char : 2; // next 2 bits (in 1st byte) are blocked out as unused unsigned char b2 : 6; // 6 bits for b2 - doesn't fit into the 1st byte => starts a 2nd unsigned char b3 : 2; // 2 bits for b3 - next (and final) bits in the 2nd byte },; int main() { std::cout (s); // usually prints 1110000011110111 // breakdown is: \_/\/\_/\____/\/ // b1 u a b2 b3 // where "u" marks the unused :2 specified in the struct, and // "a" marks compiler-added padding to byte-align the next field. // Byte-alignment is happening because b2's type is declared unsigned char; // if b2 were declared uint16_t there would be no "a", b2 would abut "u". for (auto b = i; b; b >>= 1) // print LSB-first std::cout << (b & 1); std::cout << '\n'; }, ``` why is b2 here: ```cpp // usually prints 1110000011110111 // breakdown is: \_/\/\_/\____/\/ // b1 u a b2 b3 ``` flipped? this is from
See the printing loop - it goes from the "back". I'm not sure how the conversion works exactly for the byte order to be "flipped" as well (when we make the order the same), might be endian, might be something with struct and casting... but the encoding within each byte makes sense - first fields take lower bits in the byte.