看这段代码:
struct A {
short s;
int i;
};
struct B {
short s;
int i;
};
union U {
A a;
B b;
};
int fn() {
U u;
u.a.i = 1;
return u.b.i;
}
是否保证 fn()
返回 1
?
注意:这是 this 的后续问题.
最佳答案
是的,这是定义的行为。首先让我们看看标准对 A
和 B
有什么看法。 [class.prop]/3有
A class S is a standard-layout class if it:
- has no non-static data members of type non-standard-layout class (or array of such types) or reference,
- has no virtual functions and no virtual base classes,
- has the same access control for all non-static data members,
- has no non-standard-layout base classes,
- has at most one base class subobject of any given type,
- has all non-static data members and bit-fields in the class and its base classes first declared in the same class, and
- [...] (nothing said here has any bearing in this case)
所以A
和B
都是标准布局类型。如果我们看[class.mem]/23
Two standard-layout struct types are layout-compatible classes if their common initial sequence comprises all members and bit-fields of both classes ([basic.types]).
The common initial sequence of two standard-layout struct types is the longest sequence of non-static data members and bit-fields in declaration order, starting with the first such entity in each of the structs, such that corresponding entities have layout-compatible types, either both entities are declared with the no_unique_address attribute ([dcl.attr.nouniqueaddr]) or neither is, and either both entities are bit-fields with the same width or neither is a bit-field.
In a standard-layout union with an active member of struct type T1, it is permitted to read a non-static data member m of another union member of struct type T2 provided m is part of the common initial sequence of T1 and T2; the behavior is as if the corresponding member of T1 were nominated. [ Example:
struct T1 { int a, b; }; struct T2 { int c; double d; }; union U { T1 t1; T2 t2; }; int f() { U u = { { 1, 2 } }; // active member is t1 return u.t2.c; // OK, as if u.t1.a were nominated }
— end example ] [ Note: Reading a volatile object through a glvalue of non-volatile type has undefined behavior ([dcl.type.cv]). — end note ]
然后我们得到类具有相同的公共(public)初始序列,布局相同,并且访问非事件类型的相同成员被视为访问事件类型的成员。
关于c++ - 布局兼容类型的 union ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53051088/