c++ - 在整个 union 上使用 std::memcpy 是否保证保留事件的 union 成员?

标签 c++ undefined-behavior unions memcpy

在 C++ 中,从最近编写的 union 成员(即事件 union 成员)中读取是明确定义的。

我的问题是是否std::memcpy将整个 union 对象复制到未初始化的内存区域,而不是将特定 union 成员复制到未初始化的内存区域将保留事件 union 成员。

union A {
    int x;
    char y[4];
};

A a;
a.y[0] = 'U';
a.y[1] = 'B';
a.y[2] = '?';
a.y[3] = '\0';

std::byte buf[sizeof(A)];
std::memcpy(buf, &a, sizeof(A));

A& a2 = *reinterpret_cast<A*>(buf);

std::cout << a2.y << '\n'; // is `A::y` the active member of `a2`?

最佳答案

你的作业没问题,因为 the assignment to non-class member a.y "begins its lifetime" .但是,您的 std::memcpy不这样做,所以对 a2 的成员的任何访问无效。因此,您依赖于未定义行为的后果。从技术上讲。在实践中,大多数工具链对原始类型 union 成员的别名和生命周期都相当宽松。

不幸的是,这里有更多的 UB,因为您违反了 union 本身的别名:您可以假装 T是一堆字节,但是 you can't pretend that a bunch of bytes is a T ,不管多少reinterpret_cast你做的。你可以实例化一个 A a2通常和 std::copy/std::memcpy来自 a ,然后你就回到了 union 成员的终身问题,如果你关心的话。但是,我想,如果这个选项对你开放,你只会写 A a2 = a首先…

关于c++ - 在整个 union 上使用 std::memcpy 是否保证保留事件的 union 成员?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62253409/

相关文章:

c - 在分配变量时获取变量的地址是否合法?

c - 结构变量别名

嵌套在 union 内的结构中的通用初始序列 - C 标准中的定义

c++ - 为什么只有边界描述符的安全设置是不够的?

c++ - 无法将矩阵转换为四元数并返回

c++ - 我应该返回一个值还是抛出异常......?

c++ - 为什么 glGetProgramiv GL_ACTIVE_UNIFORMS 偶尔会返回垃圾并使我的程序崩溃?

c - 有什么方法可以保证段错误吗?

c++ - 仅在两个成员都参数化后使用模板模板参数构建错误

C 预处理器计算最大 sizeof 结构