联合中的标量成员是否计入共同的初始序列?

And*_*dyG 4 c++ unions language-lawyer c++17

union U下面,如果a或者b是活动成员,是否定义了要访问的行为c

struct A{
    int a;
};
struct B{
    int a;
    double b;
};
union U{
    A a;
    B b;
    int c;
};
Run Code Online (Sandbox Code Playgroud)

[class.union]中,标准定义了一些使用union更简单(强调我的)的规则:

[注意:为了简化联合的使用,我们做了一个特别的保证:如果标准布局联合包含多个共享一个公共初始序列的标准布局结构,并且该标准的对象是非静态数据成员-layout union类型是活动的并且是标准布局结构之一,允许检查任何标准布局结构成员的公共初始序列; 见[class.mem]. - 结束说明]

我在这里挂了单词struct.int即使它不是结构,标准布局标量是否会计数?

  • 我的union U上面确实是[class]之后的"标准布局"联合,它基本上说它需要是一个使用union关键字的标准布局类,而且因为我们只使用标量(标准布局类型),所以它会通过.

  • 结构显然共享一个由第一个成员组成的共同初始序列int,但不清楚基本类型是否可以考虑用于常见的初始序列.

    • [class.union]还说"每个非静态数据成员都被分配,就好像它是结构的唯一成员一样." 我认为这证明它是定义的.
  • 最后,标准布局结构不允许在开头有填充([class.mem]),并且union的成员是指针可互换的,因此标准告诉我们int标准布局中的元素结构,而非int c联合中的static 保证对齐.

Eri*_*hil 6

struct A并且struct B是:

  • 包含在标准布局中union U,
  • 标准布局结构,和
  • 共享一个共同的初始序列.

因此,它们满足句子中的描述"如果标准布局联合包含几个共享共同初始序列的标准布局结构......".

联合中的int c那个也不是这样的结构,也不是这样的结构.所以,这句话是不是告诉你,你可以写c和检查a.ab.a,也不是说你可以写a.ab.a和检查c.

这意味着它c不是您可以检查的常见初始序列的一部分.但它也不破坏的公共初始序列struct Astruct B.

关于文本"每个非静态数据成员被分配就好像它是结构的唯一成员",标准在这里使用语言有点草率.分配通常是指获取或保留存储,但这种用法似乎指的是在给定的存储空间中布置对象的字节.我没有看到C++标准中的正式定义(但我看起来并不太难),但我确实找到了类似的用法.所以我认为这意味着每个非-static数据成员的布局就好像它是唯一的成员一样.

这说明指向这些联盟成员中的任何一个的指针指向与指向任何其他联盟成员的指针相同的位置.这可能意味着指向一个的指针可以转换为指向另一个的指针.但是,它不会授予您违反严格别名规则的许可.即使x是一个指针cy一个指针a或者a.a,您不能使用*x访问c,同时a是最后写入成员或使用*yc是最后写入的成员.