c++ - union 中的标量成员是否计入公共(public)初始序列?

标签 c++ language-lawyer c++17 unions

在下面的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 这样的标准布局标量是否也算数?

  • 我上面的 union U 确实是 [class] 之后的“标准布局” union 这基本上是说它需要是一个使用 union 关键字的标准布局类,因为我们只使用标量(标准布局类型),所以它通过了。

  • 这些结构显然共享一个 common initial sequence它由第一个 int 成员组成,但尚不清楚是否可以将基本类型视为公共(public)初始序列。

    • [class.union]还说“每个非静态数据成员都被分配为就好像它是结构的唯一成员一样。”我认为这提供了它被定义的证据。
  • 最后,标准布局结构不允许在开头有填充([class.mem]), union 的成员是pointer interconvertible。所以标准告诉我们标准布局结构中的 int 元素和 union 中的非静态 int c 保证对齐。

最佳答案

struct Astruct B是:

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

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

int c that also in the union is not such a struct 也不在这样的结构中。所以这句话不是告诉你可以写给c并检查 a.ab.a ,也不能写信给 a.ab.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/

相关文章:

c++ - 为什么 "std::async"没有按预期工作?

c++ - C++17 中的数组赋值

c++ - 如何在 utf8 中获取代码点文字

c++ - 您必须选择一个主机应用程序才能运行仅命令目标吗?代码:: block

c++ - 如何从以 4096 字节拆分的子进程进行管道传输?

c++ - 嵌套类指针访问

rust - Rust的确切自动引用规则是什么?

java - toString() 是否定义为为 java.lang.String 返回 this?

c - 重复 printf 说明符标志时的行为是什么?

c++ - 为什么这个循环模板实例化是合法的?