Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Storing 8 logical true/false values inside 1 byte?

Tags:

c++

bit-fields

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?

like image 776
Jazcash Avatar asked Apr 24 '15 19:04

Jazcash


People also ask

Is Boolean stored in a byte?

Boolean variables are stored as 16-bit (2-byte) numbers, but they can only be True or False.


3 Answers

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;
};
like image 109
Carl Norum Avatar answered Oct 19 '22 03:10

Carl Norum


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

like image 36
dtech Avatar answered Oct 19 '22 03:10

dtech


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 or false is stored into a bit-field of type bool of any size (including a one bit bit-field), the original bool 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;.

like image 3
Potatoswatter Avatar answered Oct 19 '22 02:10

Potatoswatter