是否在整个联合上使用std :: memcpy保证保留活动的联合成员?

问题描述 投票:3回答:2

在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`?
c++ undefined-behavior unions memcpy
2个回答
0
投票
由于the assignment to non-class member a.y "begins its lifetime",您的作业还可以。但是,您的a.y不会这样做,因此对std::memcpy成员的任何访问均无效。因此,您依赖未定义行为的后果。从技术上讲。实际上,大多数工具链对于原始类型联合成员的别名和生存期都比较松懈。

[不幸的是,这里有更多的UB,因为您违反了联合本身的别名:您可以假装a2是一堆字节,但是不能假装一堆字节是[C0 ],无论您进行多少T操作。您可以正常地实例化一个T,然后从reinterpret_cast实例化一个A a2 / std::copy,然后,如果您关心的话,您将回到工会成员的生存期问题。但是,我想,如果您可以使用此选项,那么您首先只是要编写std::memcpy ...


0
投票
我的问题是,a是否将整个联合对象(而不是将特定的联合成员复制到未初始化的存储区中,将保留活动的联合成员。)>

将按预期复制。

这是您读取结果的方式,该结果可能会或可能不会使您的程序具有未定义的行为。


使用A a2 = astd::memcpy从一个来源复制到一个目的地。可以复制原始内存。无法读取

from

内存as尚未初始化的内容。
© www.soinside.com 2019 - 2024. All rights reserved.