c++ - 布局兼容类型的 union

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

看这段代码:

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 的后续问题.

最佳答案

是的,这是定义的行为。首先让我们看看标准对 AB 有什么看法。 [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)

所以AB都是标准布局类型。如果我们看[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]).

[class.mem]/22

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.

[class.mem]/25

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/

相关文章:

c - 为什么我不能检索我的灵活数组成员大小?

c++ - 为什么非平凡成员需要在同一类中为匿名 union 定义构造函数

C++ 库和自注册类 : Factory map empty in client application

C++17:编译器支持 pmr 命名空间类

c# - 将 c# 结构传递给非托管 C++ DLL 时出现 SafeArrayTypeMismatchException

c++ - 从文件发出阅读空间

xpath - 为什么点 (.) 的定义在 XPath 1.0 和 2.0 之间发生变化?

c++ - 为什么编译器不自动内联自由定义的函数?而是导致链接器错误

c++ - 使用 C++17 功能更好地从容器中删除所有指针

c++ - 使用 DirectXTex 库