c++ - 包含包装类型和类型本身的 union 是否有任何保证?

标签 c++ struct types language-lawyer unions

我可以将一个 T 和一个包装的 T 放在一个 union 中并根据需要检查它们吗?

union Example {
    T value;
    struct Wrapped { 
       T wrapped;
    } wrapper;
};
// for simplicity T = int

Example ex;
ex.value = 12;
cout << ex.wrapper.wrapped; // ?

C++11 标准只保证公共(public)初始序列的保存检查,但 value 不是 struct。我猜想答案是,因为wrapped types aren't even guaranteed to be memory compatible to their unwrapped counterpartaccessing inactive members is only well-defined on common initial sequences .

最佳答案

我认为这是未定义的行为。

[class.mem]给我们:

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 and either neither entity is a bit-field or both are bit-fields with the same width. [...]

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.

如果 T 不是标准布局结构类型,这显然是未定义的行为。 (请注意,int 不是标准布局结构类型,因为它根本不是类类型)。

但即使对于标准布局结构类型,构成“公共(public)初始序列”的内容也严格基于非静态数据成员。即 Tstruct { T val; 没有共同的初始序列 - 根本没有共同的数据成员!

因此,这里:

template <typename T>
union Example {
    T value;
    struct Wrapped { 
       T wrapped;
    } wrapper;
};


Example<int> ex;
ex.value = 12;
cout << ex.wrapper.wrapped; // (*)

您正在访问一个不活跃的联盟成员。这是未定义的。

关于c++ - 包含包装类型和类型本身的 union 是否有任何保证?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48058545/

相关文章:

c++ - 当在 std::list<shared_ptr> 的 C++14 初始化列表中间抛出时,GCC(但不是 Clang)下的内存泄漏

c++ - OpenGL故障;抗锯齿 MSAA 8x 后白线中的黑色像素

c - struct 的底层是如何工作的?

Python 无法识别 namedtuple 的类型

types - 使用 cfspreadsheet 读取列格式

C++如何接受服务器推送数据?

c++ - 文件修改或文件打开时的断点

go - 为这个用例构建 go 项目

c++ - union typedef 中的冗余字节

haskell - 没有 (Floating Int) 实例