I would like to model a status register in C/C++, which should be accessible as std::bitset and as std::uint8_t. Thus I would combine them as union as follows:
#include <bitset>
#include <iostream>
union byte {
std::uint8_t uint;
std::bitset<8> bitset;
};
int main(int, char*[])
{
byte b = { .uint = 0b10101010 };
std::cout << "Value of bit 5: "
<< (b.bitset.test(5) ? "true" : "false") << std::endl;
std::cout << "Value of bit 4: "
<< (b.bitset.test(4) ? "true" : "false") << std::endl;
std::cout << "Bitset Output: " << b.bitset << std::endl;
std::cout << "Uint Output: " << static_cast<int>(b.uint) << std::endl;
return 0;
}
This seems to work as expected, when compiled with GCC x86_64 8.2. However, I would like to know if I could expect this to work in all cases or if I am better off with some helper functions like bitset, bittest, ...
uint8_t), to avoid UB. - Dan M.std::bitsethave to be directly compatible with a built-in type corresponding to the bit-size. All in all, attempting to do what you do will lead to undefined behavior - Some programmer dudestd::bitsetis the number of bits not bytes. - Some programmer dudeuint8_tand handle bits in a "nice" way, then you have to implement such a class yourself. If you need it to map to a memory-mapped hardware register it should probably wrap a pointer to the register. - Some programmer dudebitset<N>is not guaranteed to take exactlyN/8bytes. See godbolt.org/z/oBRgT9 There is nothing wrong with my statement. - Dan M.