我试图更好地理解关于联合和通用初始序列规则的一个相当令人惊讶的发现。常见的初始序列规则说(class.mem 23):
因此,鉴于:
struct A {
int a;
double x;
};
struct B {
int b;
};
union U {
A a;
B b;
};
U u;
u.a = A{};
int i = u.b.b;
这是已定义的行为,
i
应具有值0
(因为A
和B
具有其第一个成员的CISt,int
)。到现在为止还挺好。令人困惑的是,如果将B
替换为一个简单的int:union U {
A a;
int b;
};
...
int i = u.b;
根据常见初始序列的定义:
因此,CIS只能在两个标准布局结构之间应用。然后:
因此,原始类型绝对不符合条件。那是因为它不能包含任何带有CISt的CIS,因此
A
没有带有int
的CIS。因此,标准说第一个示例是定义的行为,而第二个示例是UB。这对我根本没有任何意义。直观上来说,编译器至少受基本类型的限制和与类的限制一样。如果这是故意的,那么为什么这有道理或理由(也许与对齐有关)?可能是缺陷吗? 最佳答案
ninjalj has it right:此规则的目的是支持tagged unions(在前面带有标签)。尽管此类联合中支持的一种类型可能是无状态的(除了标签之外),但通过制作仅包含标签的结构,可以轻松解决这种情况。因此,不需要将规则扩展到结构之外,并且默认情况下,出于优化的通常原因和 future 标准化的灵活性,应将此类未定义行为的异常(exception)情况(在这种情况下类似于严格的别名)保持在最低水平。