位域是否算作具有相同类型的整个 int 的公共初始序列?

Gui*_*cot 5 c++ unions language-lawyer

我想知道以下是否是有效的 C++:

union id {
    struct {
        std::uint32_t generation : 8;
        std::uint32_t index : 24;
    };
    std::uint32_t value;
};
Run Code Online (Sandbox Code Playgroud)

我想要这个,这样我就可以同时访问generationindex,从而保持对整个号码的访问。既然都是std::uint32_t,那应该不是UB吧?

我打算这样使用它:

auto my_id = id{
    .generation = 1,
    .index = 4,
};

auto my_id_value = std::uint32_t{id.value};
Run Code Online (Sandbox Code Playgroud)

如果是 UB,是否有另一种方法可以使其工作并根据 C++ 标准有效?

use*_*522 2

根据CWG 645的决议(对于 C++11;不确定它是否应该作为 DR 应用到 C++98),公共初始序列需要两个类中相应的非静态数据成员或位字段(通过声明order)要么都是位字段(具有相同的宽度),要么都不是位字段。

相关措辞仍然可以在当前草案的[class.mem.general]/23中找到,其中包括一个示例,清楚地说明与非静态数据成员类型相同的位字段不会成为共同的初始序列。

因此,[class.mem.general]25中允许访问联合中标准布局类成员的公共初始序列中的非活动成员的例外规则不适用于您的情况,并且读入id.value具有auto my_id_value = std::uint32_t{id.value};未定义的行为。