无符号短段位域和匿名位域的合并

Union of unsigned short and anonymous bitfield

提问人:deponovo 提问时间:10/29/2023 最后编辑:deponovo 更新时间:10/29/2023 访问量:65

问:

最小示例:

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};
}

我的位域的确切表示是不同的,在这里无关紧要。重要的部分是它按照我的期望和要求工作(带有位域的 2 字节信息),但将数据截断为 4 位,确切地说?v2_tv1_td1

C++ 联合 位域

评论

0赞 BoP 10/29/2023
在情况 1 中,值 256 将存储在 中。而且它不合适。d1
0赞 deponovo 10/29/2023
从务实的角度来看,这是有道理的。你有相关文档的链接吗?例如,为什么不将第一种情况视为许多位域的组?
0赞 David C. Rankin 10/29/2023
256二进制表示是100000000
0赞 BoP 10/29/2023
我没有对所有聚合初始化的正式描述。但是,在这种情况下,大括号省略“允许”跳过结构的内大括号(即使不是故意的)。
1赞 David C. Rankin 10/29/2023
请参阅 C++ 标准 [class.bit]“未命名的位字段不是成员,无法初始化。"

答:

0赞 deponovo 10/29/2023 #1

每个联盟字段的统一初始化将遵循声明成员的顺序。

例如,相当于 (C++20),它显然会截断数据(这样放下,当前行为变得明显)。v1_t {256};v1_t {.d1=256};

另一方面,第一个数据成员是 ,因此等价于产生我预期的结果和行为。v2_tdatav2_t {256};v2_t {.data=256};

v1_t分别启用大括号省略,例如 for 和字段,但我有许多不同的大小不同的位字段,并且初始化必须在类型之间保持一致。{11, 2}d1d2

我的项目中当前使用的标准是 C++17,因此初始化可能性不可用,这就是为什么我认为提供“预期”行为的标准。{.data}v2_t

评论

0赞 user17732522 10/30/2023
"这显然会截断数据(这样放下,当前行为变得很明显).“:不能保证该值会被截断。该行为是按 eel.is/c++draft/dcl.init#general-16.9.sentence-4 实现定义的。