如何在C++中正确使用union?
How to use union in C++ correctly?
我在 C++ 中有以下联合
union MsgData {
struct
{
uint32_t msb : 1;
uint32_t reg_addr : 7;
uint32_t data : 8;
uint32_t fill : 3;
uint32_t crc : 5;
} bits;
uint8_t bytes[3];
};
如果我执行以下操作(address
包含 26
,data
包含 255
- 均为十进制):
msg.bits.msb = 1;
msg.bits.reg_addr = (address & 0x7F);
msg.bits.data = data;
msg.bits.fill = 0;
msg.bits.crc = 0;
联合 MsgData
中的字节数组 bytes
包含:
msg.bytes[0]: 53
msg.bytes[1]: 255
msg.bytes[2]: 0
我期望 msg.bytes[0]
中的值为 154
。谁能给我一个建议,为什么我在 msg.bytes[0]
中得到 53
而不是 154
值?
你的程序的行为是未定义的,因为你从联合会的一个不活跃的成员那里读取。
How to use union in C++ correctly?
总的来说:仅从最后分配的联合的活动成员读取。确实存在例外。例如,也允许从与活动成员具有相同类型的非活动成员读取。没有适用于您的程序的此类例外情况。
既然你想把类型双关成字节数组,还有另一种定义明确的方式:reinterpret_cast
:
struct
{
...
} bits;
static_assert(std::is_same_v<uint8_t, unsigned char>);
uint8_t* bytes = reinterpret_cast<uint8_t*>(&bits);
请注意,通过此 bytes
指针进行读取是特别允许的,因为 unsigned char
(以及其他一些类型)很特殊。
现在,假设您使用定义联合类型双关行为的语言扩展或使用上面显示的 reinterpret_cast
:
Can anybody give me an advice why I have got 53 instead of 154 value in the msg.bytes[0]?
因为这个:
reg_addr | msb | bit field
7654321 | 0 | bit index in order of significance
0011010 | 1 | bit value
0b00110101 == 53
不清楚您为什么会有其他预期。依赖位字段的顺序是不可移植的。
我在 C++ 中有以下联合
union MsgData {
struct
{
uint32_t msb : 1;
uint32_t reg_addr : 7;
uint32_t data : 8;
uint32_t fill : 3;
uint32_t crc : 5;
} bits;
uint8_t bytes[3];
};
如果我执行以下操作(address
包含 26
,data
包含 255
- 均为十进制):
msg.bits.msb = 1;
msg.bits.reg_addr = (address & 0x7F);
msg.bits.data = data;
msg.bits.fill = 0;
msg.bits.crc = 0;
联合 MsgData
中的字节数组 bytes
包含:
msg.bytes[0]: 53
msg.bytes[1]: 255
msg.bytes[2]: 0
我期望 msg.bytes[0]
中的值为 154
。谁能给我一个建议,为什么我在 msg.bytes[0]
中得到 53
而不是 154
值?
你的程序的行为是未定义的,因为你从联合会的一个不活跃的成员那里读取。
How to use union in C++ correctly?
总的来说:仅从最后分配的联合的活动成员读取。确实存在例外。例如,也允许从与活动成员具有相同类型的非活动成员读取。没有适用于您的程序的此类例外情况。
既然你想把类型双关成字节数组,还有另一种定义明确的方式:reinterpret_cast
:
struct
{
...
} bits;
static_assert(std::is_same_v<uint8_t, unsigned char>);
uint8_t* bytes = reinterpret_cast<uint8_t*>(&bits);
请注意,通过此 bytes
指针进行读取是特别允许的,因为 unsigned char
(以及其他一些类型)很特殊。
现在,假设您使用定义联合类型双关行为的语言扩展或使用上面显示的 reinterpret_cast
:
Can anybody give me an advice why I have got 53 instead of 154 value in the msg.bytes[0]?
因为这个:
reg_addr | msb | bit field
7654321 | 0 | bit index in order of significance
0011010 | 1 | bit value
0b00110101 == 53
不清楚您为什么会有其他预期。依赖位字段的顺序是不可移植的。