I wrote this code just for the fun of it:
union {
struct {
bool a : 1;
bool b : 1;
bool c : 1;
bool d : 1;
bool e : 1;
bool f : 1;
bool g : 1;
bool h : 1;
} a;
uint8_t b;
} uni {0}; // sets .a bits to false
// union size : 1 byte
I can toggle each bit individually:
uni.a.a = true;
uni.a.d = true;
cout << bitset<8>(uni.b) << endl; // Prints 000010001
And also use bit masks:
uni.b = 0b00001000;
if(uni.a.a) cout << "a";
if(uni.a.b) cout << "b";
if(uni.a.c) cout << "c";
if(uni.a.d) cout << "d";
if(uni.a.e) cout << "e";
if(uni.a.f) cout << "f";
if(uni.a.g) cout << "g";
if(uni.a.h) cout << "h";
// prints 'd'
I know there are other ways to do this (bitwise operations) but I like this design. My question is: is this a good use of bitfields and unions, in terms of reliability and performance?
My question is: is this a good use of bitfields and unions, in terms of reliability and performance?
In terms of performance, what you are doing is probably as good as it is going to get, at least in terms of accessing memory at the bit level.
In terms of reliability, it is probably OK across most modern systems. At the risk of sounding like a language lawyer, here are some areas where it could have different results across systems:
sizeof(bool)
isn't guaranteed to be 1, that is bool
can be stored in memory larger than one byte. I don't know of any modern system where bool
isn't the size of a byte, but you could imagine an older or bad implementation that makes bool
to be the same size as an int
. This would inherently throw off your union
.union
can caused undefined behaviorunion
would represent the MSB.struct
, but that doesn't have to happen.struct
such that individual bits are in different bytes of memory. Again, all implementations that I know of won't do this but it can happen.I don't think you would need to worry about the above. But, in terms of covering everything that could go wrong, I think the above list pretty well covers the really odd-ball scenarios that you could face if you really searched for an implementation that was a bit different.