Storing 8 boolean true / false values ​​within 1 byte?

I am working on a microcontroller with only 2k SRAM and desperately need some memory storage. Trying to figure out how I can put 8 0/1 values ​​in one byte using a bit field, but I can't fully implement it.

 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?

+65
c ++ bit-fields
Apr 24 '15 at 19:16
source share
4 answers

All your bitfield members are signed with 1-bit integers. In a system with two additions, this means that they can only represent 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; }; 
+112
Apr 24 '15 at 7:19
source share

As a warning, the standard does not actually apply an implementation scheme for bitfields. There is no guarantee that Bits will be 1 byte, and it is hypothetically possible that it will be larger.

In practice, however, actual implementations usually follow obvious logic, and it will be "almost always" 1 byte in size, but again, there is no requirement that it be guaranteed. Just in case, if you want to be sure, you can do it manually .

BTW -1 is still true , but it is -1 != true

+13
Apr 24 '15 at 21:06
source share

As already noted, these variables consist only of a signed bit, so the only available values ​​are 0 and -1 .

A more suitable type for these bit fields would be bool . C ++ 14 §9.6 / 4:

If true or false stored in a bool field of type any size (including a single-bit bit field), the original bool value and the bit field value are compared equal.

Yes, std::uint8_t will do the job, but you can also use the best fit. You won’t need things like throwing for std::cout << (int)b.b0; .

+2
Apr 25 '15 at 11:51 on
source share

Integer and unsigned integers are the answer.

Keep in mind that signal transmission is just an interpretation of bits, -1 or 1 is just a “print” serializer that interprets a “variable type” because it was "discovered" for the cout functions (operator overloading) by the compiler, the bit is the same, its value is also (on / off) - since you have only 1 bit.

Do not worry about this, but it is good practice to be explicit, so prefer to declare your variable unsigned, it instructs the compiler to set the correct code when you set or get a value for a serializer like "print" (cout).

"COUT" OVERLOADING THE OPERATOR: "cout" works through a series of functions that overloads the parameter with the instructions of the compiler that calls the function. Thus, there are two functions: one receives unsigned and the other signed, so they can interpret the same data in different ways, and you can change them by telling the compiler to call the other using a cast. See cout <MyClass

0
Jul 08 '15 at 15:34
source share



All Articles