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

Do scalar members in a union count towards the common initial sequence?

在下面的union U中,如果ab是活跃成员,是否定义了访问c的行为?

struct A{
    int a;
};
struct B{
    int a;
    double b;
};
union U{
    A a;
    B b;
    int c;
};

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

[ Note: One special guarantee is made in order to simplify the use of unions: If a standard-layout union contains several standard-layout structs that share a common initial sequence, and if a non-static data member of an object of this standard-layout union type is active and is one of the standard-layout structs, it is permitted to inspect the common initial sequence of any of the standard-layout struct members; see [class.mem].  — end note ]

我被 struct 这个词挂断了。即使不是结构,像 int 这样的标准布局标量是否也算数?

struct Astruct B 是:

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

因此,它们满足句子“如果标准布局联合体包含多个共享公共初始序列的标准布局结构......”中的描述。

同在union中的int c不是这样的struct,也不在这样的struct中。所以这句话不是告诉你可以写入 c 并检查 a.ab.a,也不是告诉你可以写入 a.ab.a 并检查c.

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

的公共初始序列

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

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