在下面的联合U中,如果a或b是活动成员,是否定义了访问c的行为?
struct A{
int a;
};
struct B{
int a;
double b;
};
union U{
A a;
B b;
int c;
};
在[class.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一样?
>上面的我的联盟U确实是[class]之后的“标准布局”联盟,它基本上说它需要是一个使用union关键字的标准布局类,而且因为我们只使用标量(标准布局类型),所以它会通过.
>结构显然共享一个由第一个int成员组成的common initial sequence,但不清楚基本类型是否可以考虑用于常见的初始序列.
> [class.union]还说“每个非静态数据成员都被分配,就像它是结构的唯一成员一样.”我认为这证明它是定义的.
>最后,标准布局结构不允许在开头([class.mem])有填充,并且union的成员是pointer interconvertible,因此标准告诉我们标准布局结构中的int元素和非静态int c在联盟中保证对齐.
解决方法:
struct A和struct B是:
>包含在标准布局联合U中,
>标准布局结构,和
>共享一个共同的初始序列.
因此,它们满足句子中的描述“如果标准布局联合包含几个共享共同初始序列的标准布局结构……”.
同时在union中的int c也不是这样的结构,也不是这样的结构.所以这句话并没有告诉你,你可以写c并检查a.a或b.a,也不是你可以写a.a或b.a并检查c.
这意味着c不是您可以检查的公共初始序列的一部分.但它也不会破坏结构A和结构B的共同初始序列.
关于文本“每个非静态数据成员被分配就好像它是结构的唯一成员”,标准在这里使用语言有点草率.分配通常是指获取或保留存储,但这种用法似乎指的是在给定的存储空间中布置对象的字节.我没有在C标准中看到正式的定义(但我看起来并不太难),但我确实找到了类似的用法.所以我认为这意味着每个非-static数据成员的布局就好像它是唯一的成员一样.
这说明指向这些联盟成员中的任何一个的指针指向与指向任何其他联盟成员的指针相同的位置.这可能意味着指向一个的指针可以转换为指向另一个的指针.但是,它不会授予您违反严格别名规则的许可.即使x是指向c的指针而y是指向a或a.a的指针,也不能使用* x来访问c,而a是最后写入的成员或使用* y而c是最后写入的成员.