I have a struct with bit-fields (totally 32 bit width) and I have a 32-bit variable. When I try to assign the variable value to my struct, I got an error:
You should never rely on how the compiler lays out your structure in memory. There are ways to do what you want with a single assignment, but I will neither recommend nor tell you.
The best way to do the assignment would be the following:
static inline void to_id(struct CPUid *id, uint32_t value)
{
id->Stepping = value & 0xf;
id->Model = value >> 4 & 0xf;
id->FamilyID = value >> 8 & 0xf;
id->Type = value >> 12 & 0x3;
id->Reserved1 = value >> 14 & 0x3;
id->ExtendedModel = value >> 16 & 0xf;
id->ExtendedFamilyID = value >> 20 & 0xff;
id->Reserved2 = value >> 28 & 0xf;
}
And the opposite
static inline uint32_t from_id(struct CPUid *id)
{
return id->Stepping
| id->Model << 4
| id->FamilyID << 8
| id->Type << 12
| id->Reserved1 << 14
| id->ExtendedModel << 16
| id->ExtendedFamilyID << 20
| id->Reserved2 << 28;
}
These are struct members, so you need to assign directly do them, or make sure the RHS of your assignment is a value of type CPUID
. Not sure why you expect to be able to assign to the struct from an integer.
The facts that the struct contains bitfields, and that the sum of the bits happens to be the same as the number of bits in the integer you're trying to assign, mean nothing. They're still not compatible types, for assignment purposes.
If this was too vague, consider showing more/better code.
Just if somebody´s interested, I´ve got a better solution for my own question:
*(reinterpret_cast<uint32_t *> (&CPUIDoutput)) = CPUIDregsoutput.EAXBuf;
Use a union.
union foo {
struct {
uint8_t a : 4;
uint8_t b : 4;
uint8_t c : 4;
uint8_t d : 4;
uint16_t e;
};
uint32_t allfields;
};
int main(void) {
union foo a;
a.allfields = 0;
a.b = 3;
return 0;
}