我有一个带有位字段的结构(总共32位宽度),我有一个32位变量。当我尝试将变量值赋给我的struct时,我收到一个错误:
错误:从'uint32_t {aka unsigned int}'转换为非标量类型'main():: CPUID'请求。
struct CPUIDregs
{
uint32_t EAXBuf;
};
CPUIDregs CPUIDregsoutput;
int main () {
struct CPUID
{
uint32_t Stepping : 4;
uint32_t Model : 4;
uint32_t FamilyID : 4;
uint32_t Type : 2;
uint32_t Reserved1 : 2;
uint32_t ExtendedModel : 4;
uint32_t ExtendedFamilyID : 8;
uint32_t Reserved2 : 4;
};
CPUID CPUIDoutput = CPUIDregsoutput.EAXBuf;
你知道如何以最短的方式做到这一点吗?感谢
P.S。当然我在实际代码中有更合适的EAX值,但我想这不会影响到这里。
答案 0 :(得分:8)
您永远不应该依赖编译器如何在内存中布局您的结构。有一些方法可以通过单一作业完成您想要的任务,但我既不会推荐也不会告诉您。
完成作业的最佳方式如下:
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;
}
相反的
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;
}
答案 1 :(得分:3)
使用联盟。
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;
}
答案 2 :(得分:2)
如果有人感兴趣,我已经为自己的问题找到了更好的解决方案:
*(reinterpret_cast<uint32_t *> (&CPUIDoutput)) = CPUIDregsoutput.EAXBuf;
答案 3 :(得分:1)
这些是struct成员,因此您需要直接指定它们,或者确保赋值的RHS是CPUID
类型的值。不确定为什么你希望能够从整数分配给结构。
结构包含位域的事实,以及位的总和恰好与您尝试分配的整数中的位数相同,没有任何意义。出于分配目的,它们仍然是不兼容的类型。
如果这太模糊,请考虑显示更多/更好的代码。