在下面的union U
中,如果a
或b
是活跃成员,是否定义了访问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
这样的标准布局标量是否也算数?
我上面的
union U
确实是 [class] 之后的“标准布局” union 这基本上是说它需要是一个使用union
关键字的标准布局类,因为我们只使用标量(标准布局类型),所以它通过了。这些结构显然共享一个 common initial sequence它由第一个
int
成员组成,但尚不清楚是否可以将基本类型视为公共(public)初始序列。- [class.union]还说“每个非静态数据成员都被分配为就好像它是结构的唯一成员一样。”我认为这提供了它被定义的证据。
- 最后,标准布局结构不允许在开头有填充([class.mem]), union 的成员是pointer interconvertible。所以标准告诉我们标准布局结构中的
int
元素和 union 中的非静态int c
保证对齐。
最佳答案
struct A
和 struct B
是:
- 包含在标准布局中
union U
, - 标准布局结构,以及
- 共享一个共同的初始序列。
因此,它们满足句子“如果标准布局 union 体包含多个共享公共(public)初始序列的标准布局结构......”中的描述。
int c
that also in the union is not such a struct 也不在这样的结构中。所以这句话不是告诉你可以写给c
并检查 a.a
或 b.a
,也不能写信给 a.a
或 b.a
并检查 c
.
这意味着c
不是您可以检查的常见初始序列的一部分。但它也不会破坏 struct A
的公共(public)初始序列。和 struct B
.
关于文本“每个非静态数据成员都被分配为就好像它是结构的唯一成员”,标准在这里的语言有点草率。分配通常指的是获取或保留存储,但是这个使用似乎是指在给定存储中布置对象的字节。我没有在 C++ 标准中看到正式定义(但我没有看得太难),但我确实找到了类似的用法。所以我认为它的意思是每个非静态数据成员的布局就像它是唯一的成员一样。
这意味着指向这些 union 成员中的任何一个的指针与指向任何其他 union 成员的指针指向相同的位置。这可能意味着指向一个的指针可以转换为指向另一个的指针。但是,它不授予您违反严格别名规则的许可。即使x
是指向 c
的指针和 y
是指向 a
的指针或 a.a
, 你不能使用 *x
访问 c
同时 a
是最后写入的成员或使用 *y
同时 c
是最后写入的成员。
关于c++ - union 中的标量成员是否计入公共(public)初始序列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48209179/