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