union 成员的 C++ 生命周期

标签 c++ initialization language-lawyer unions object-lifetime

在当前版本的C++标准草案中,[basic.life]/1状态:

The lifetime of an object or reference is a runtime property of the object or reference. A variable is said to have vacuous initialization if it is default-initialized and, if it is of class type or a (possibly multi-dimensional) array thereof, that class type has a trivial default constructor. The lifetime of an object of type T begins when:

  • storage with the proper alignment and size for type T is obtained, and

  • its initialization (if any) is complete (including vacuous initialization) ([dcl.init]),

except that if the object is a union member or subobject thereof, its lifetime only begins if that union member is the initialized member in the union ([dcl.init.aggr], [class.base.init]), or as described in [class.union]. [...]

从该段我了解到, union 成员开始其生命周期的唯一方式是:

  • 该成员“是 union 中的初始化成员”(例如,如果它在 mem-initializer 中被引用),或者
  • [class.union]中提到的一些其他方式

但是,[class.union] 中唯一的规范 段落指定了 union 成员如何开始其生命周期是 [class.union]/5 (但它仅适用于特定类型,即 non-classnon-array 或具有 trivial< 的 class 类型 未删除的构造函数,或此类类型的数组)。

下一段,[class.union]/6 (包含注释和示例,因此它不包含规范文本),描述了一种通过使用placement new-expression 来更改 union 的事件成员的方法,比如new (&u.n) N;,其中

struct N { N() { /* non-trivial constructor */ } };
struct M { M() { /* non-trivial constructor */ } };

union 
{
    N n;
    M m;
} u;

我的问题是,标准中的哪个地方规定了 new (&u.n) N; 开始 u.n 的生命周期?

谢谢!

最佳答案

关于此的重要规则是:

[class.union]/1

In a union, a non-static data member is active if its name refers to an object whose lifetime has begun and has not ended ([basic.life]). ...

就此规则而言,事件成员可以在成员对象开始其生命周期的任何时间更改。规则 [class.union]/5 还允许通过分配给一组有限类型的非事件成员来更改事件成员。缺少单独的新放置规则本身并不禁止更改成员。如果它开始于成员的生命周期,则该成员是联盟的活跃成员。

所以,[basic.life/1] 说成员的生命周期只有在 [class.union] 这么说1 时才开始,而 [class.union/1] 说成员仅当其生命周期开始时才处于事件状态2。这看起来确实有点像第 22 条军规。

我以一种有意义的方式阅读规则的最佳尝试是解释 placement-new 开始成员的生命周期,因此 [class.union/1] 适用,因此 “或如[class.union]" 适用,因此突出显示的异常(exception)不适用。接下来我想说生命因此开始,但这个逻辑是循环的。

非规范的 [class.union]/6 说得很清楚,放置 new 的目的是允许的,但是规范的规则很纠结。我会说措辞可以改进。


1(或者当 union 使用该成员初始化时,这不是我们正在考虑的情况)

2(或根据 [class.union]/5 分配后,我们正在考虑的情况并非如此)

关于 union 成员的 C++ 生命周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57877884/

相关文章:

swift - 如何使用 EnvironmentObject 在 SwiftUI 中初始化 State 属性?

c - 二维数组充满垃圾数据......有时

c++ - 为什么 C+ +'s <vector> templated class doesn' t 打破了一个定义规则?

c# - Marshal.SizeOf(strurtureType) 总是抛出错误

swift - 如何在 Swift 的便利初始化器中调用类方法

c++ - 没有尖括号的模板类实例化

c++ - 使用 typeid 警告未使用的变量

C++ : String + integer path

c++ - 如何解析 IP 地址 block IPv4/IPv6

c++ - 实现 graph_coloring - m 着色问题的问题