Considering following example:
#include <iostream>
using namespace std;
struct Test
{
uint8_t A:1;
uint8_t B:1;
uint8_t C:1;
uint8_t D:1;
};
int main()
{
Test test;
test.A = 1;
test.B = 0;
test.C = 1;
test.D = 0;
int bitmask = test.A | (test.B << 1) | (test.C << 2) | (test.D << 3);
cout << "Size: " << sizeof(test) << ", bitmask: " << bitmask;
return 0;
}
I'm assuming that the data in the bitfield is represented as bitmask somehow? I was wondering if there is a way to get a bitmask directly, without having to go through and shift all members. In this case it's not a big deal, but if you have large bitfield it can get pretty tedious.
For example it would be great if I could do something like this:
int bitmask = (int)test;
Of course that doesn't work. Any way to achieve similar robustness?
CodePudding user response:
Assuming you want to convert the entire struct, and there exists an integral type with the same size as the struct:
Test test;
test.A = 1;
test.B = 0;
test.C = 1;
test.D = 0;
cout << (int)std::bit_cast<char>(test) << '\n';
std::bit_cast
is a C 20 feature.
char
is used here because it has the same size as Test
. I'm casting the result to int
, because otherwise cout
interpretes the resulting number as a character code.
The alternative solution is to memcpy
the struct (or a part of it) to an integer:
char ch;
std::memcpy(&ch, &test, 1);
cout << (int)ch << '\n';
Unlike bit_cast
, this doesn't require a modern compiler, and allows you to inspect a specific part of the struct (assuming the part is byte-aligned).