【发布时间】:2018-06-20 21:47:01
【问题描述】:
在下面的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 的使用更容易(强调我的):
[ 注意:为了简化联合的使用,有一个特殊的保证:如果一个标准布局联合包含多个共享一个共同初始序列的标准布局结构,并且如果一个非-此标准布局联合类型的对象的静态数据成员是活动的并且是标准布局结构之一,允许检查任何标准布局的公共初始序列struct 成员;见[class.mem]。 — 尾注 ]
我对 struct 这个词很感兴趣。像int 这样的标准布局标量即使不是结构也算数吗?
我上面的
union U确实是[class] 之后的“标准布局”联合,基本上说它需要是一个使用union关键字的标准布局类,因为我们只使用标量(标准布局类型),它通过了。-
这些结构显然共享一个common initial sequence,它由第一个
int成员组成,但尚不清楚是否可以将基本类型考虑用于常见的初始序列。- [class.union] 还说“每个非静态数据成员都被分配,就好像它是结构的唯一成员一样。”我认为这提供了它被定义的证据。
- 最后,标准布局结构不允许在开头有填充([class.mem]),联合的成员是pointer interconvertible,所以标准告诉我们标准布局结构中的
int元素,并且联合中的非静态int c保证对齐。
【问题讨论】:
-
普通的初始序列只定义为类类型的属性。访问是否有效我就不讨论了,但如果是,那肯定不是按照常见的初始顺序保证。
-
@StoryTeller:我刚刚用标准的另一个摘录更新了这个问题,关于如何分配非静态数据成员,就好像它们是 struct 的唯一成员一样,这意味着
int在union的上下文中,可以认为是标准布局结构。 -
我会告诉你更多。这些成员是pointer-interconvertible。但我不确定是否可以访问“非活动”成员。我敢打赌,不会。
-
@StoryTeller:我不清楚当你说“非活跃成员”时你是指
int c,还是包括B b(假设A a是活跃成员)跨度> -
我的意思是任何没有最后一次写信的工会成员。通俗地说,与 [class.union]/1 定义的相反。所以是的,
c和b(尽管在这种特殊情况下,c很有趣)。
标签: c++ language-lawyer c++17 unions