I'm working on a microcontroller with only 2KB of SRAM and desperately need to conserve some memory. Trying to work out how I can put 8 0
/1
values into a single byte using a bitfield but can't quite work it out.
struct Bits
{
int8_t b0:1, b1:1, b2:1, b3:1, b4:1, b5:1, b6:1, b7:1;
};
int main(){
Bits b;
b.b0 = 0;
b.b1 = 1;
cout << (int)b.b0; // outputs 0, correct
cout << (int)b.b1; // outputs -1, should be outputting 1
}
What gives?
Boolean variables are stored as 16-bit (2-byte) numbers, but they can only be True or False.
All of your bitfield members are signed 1-bit integers. On a two's complement system, that means they can represent only either 0
or -1
. Use uint8_t
if you want 0
and 1
:
struct Bits
{
uint8_t b0:1, b1:1, b2:1, b3:1, b4:1, b5:1, b6:1, b7:1;
};
As a word of caution - the standard doesn't really enforce an implementation scheme for bitfields. There is no guarantee that Bits
will be 1 byte, and hypothetically it is entirely possible for it to be larger.
In practice however the actual implementations usually follow the obvious logic and it will "almost always" be 1 byte in size, but again, there is no requirement that it is guaranteed. Just in case you want to be sure, you could do it manually.
BTW -1
is still true
but it -1 != true
As noted, these variables consist of only a sign bit, so the only available values are 0
and -1
.
A more appropriate type for these bitfields would be bool
. C++14 §9.6/4:
If the value
true
orfalse
is stored into a bit-field of typebool
of any size (including a one bit bit-field), the originalbool
value and the value of the bit-field shall compare equal.
Yes, std::uint8_t
will do the job, but you might as well use the best fit. You won't need things like the cast for std::cout << (int)b.b0;
.
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