在C ++中,从最近编写的工会成员(也称为active工会成员)中读取是明确定义的。
我的问题是,与复制特定的工会成员相比,将[[whole工会对象std::memcpy
复制到未初始化的存储区是否会保留活动的工会成员。
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`?
a.y
"begins its lifetime",您的作业还可以。但是,您的a.y
不会这样做,因此对std::memcpy
成员的任何访问均无效。因此,您依赖未定义行为的后果。从技术上讲。实际上,大多数工具链对于原始类型联合成员的别名和生存期都比较松懈。[不幸的是,这里有更多的UB,因为您违反了联合本身的别名:您可以假装a2
是一堆字节,但是不能假装一堆字节是[C0 ],无论您进行多少T
操作。您可以正常地实例化一个T
,然后从reinterpret_cast
实例化一个A a2
/ std::copy
,然后,如果您关心的话,您将回到工会成员的生存期问题。但是,我想,如果您可以使用此选项,那么您首先只是要编写std::memcpy
...
我的问题是,a
是否将整个联合对象(而不是将特定的联合成员复制到未初始化的存储区中,将保留活动的联合成员。)>将按预期复制。
这是您读取结果的方式,该结果可能会或可能不会使您的程序具有未定义的行为。
A a2 = a
将std::memcpy
从一个来源复制到一个目的地。可以复制原始内存。无法读取from
内存as尚未初始化的内容。