最小示例:
union v1_t
{
struct {
unsigned int d1 : 4;
unsigned int d2 : 4;
unsigned int : 8;
};
unsigned short data;
};
union v2_t
{
unsigned short data;
struct {
unsigned int d1 : 4;
unsigned int d2 : 4;
unsigned int : 8;
};
};
int main()
{
v1_t v1 {256}; // gets truncated to 0. This is the equivalent of v1_t {.d1=256}
v2_t v2 {256};
}
我的位域的确切表示是不同的,在这里无关紧要。重要的是
v2_t
按照我的预期和要求工作(带位字段的2字节信息),但是v1_t
将数据截断为4位,正是d1
?
各个union的字段统一按照声明成员的顺序初始化。
例如,
v1_t {256};
相当于v1_t {.d1=256};
(C++20),这显然会截断数据(这样写下来,当前的行为就很明显了)。
另一方面,对于
v2_t
,第一个数据成员是 data
,因此 v2_t {256};
相当于 v1_t {.data=256};
,它产生了我期望的结果和行为。
v1_t
分别启用大括号省略,如 {11, 2}
和 d1
字段的 d2
,但我有许多不同大小的不同位字段,并且初始化必须在类型之间保持一致。
我的项目中使用的当前标准是 C++17,因此
{.data}
初始化可能性不可用,这就是我认为 v2_t
提供“预期”行为的原因。