在什么条件下使用 std::memcpy 在对象之间复制是安全的?
Under what conditions is it safe to use std::memcpy to copy between objects?
在什么条件下使用std::memcpy
从一个对象复制到另一个对象是安全的?
例如,必须满足T
、src
和dest
哪些条件才能确保以下各项安全:
template <typename T>
void copy_bytewise(T& dest, const T& src) {
std::memcpy(&dest, &src, sizeof(T));
}
关于src
和dest
,我们唯一可以假设的是它们不与1重叠。特别是src
或dest
中的任何一个都可以是对成员或基类的引用。
我对涉及该标准的答案感兴趣,但如果这与通常的做法不同(例如,来自 Itanium 的事实上的 C++ ABI(,我也想知道。
请注意,T
满足简单可复制(TC( 概念是不够的,如此示例所示。base
是 TC 但不是 memcpy-安全的(由于对派生类的成员重用填充(。
我特别感兴趣,如果单独T
有任何条件是足够的(不一定是必要的(,而不需要src
和dest
的条件(一般来说,不能静态确定(。
1具体来说,我的假设是,如果它们确实重叠,它们仍然可以在与std::memcpy
相同的条件下T
复制,但改用std::memmove
。如果假设不正确,它可能是答案的一部分。
From [basic.types]/3:
对于任何平凡可复制的类型
T
,如果指向T
的两个指针指向不同的T
对象obj1
和obj2
,其中obj1
和obj2
都不是基类子对象,如果构成obj1
的底层字节([intro.memory](被复制到obj2
中,obj2
随后应保持与obj1
相同的值。
总之:
必须满足哪些条件才能确保以下安全
T
必须是微不足道的可复制的;这是T
必须满足的唯一条件。另一个要求不是对T
的限制,而是对可能被复制的对象的性质的限制。这意味着这不是你可以静态确定的东西。
相关文章:
- 复制和交换习惯用法与移动操作之间的交互
- 填充上编译器生成的复制构造函数之间的不一致
- 在什么条件下使用 std::memcpy 在对象之间复制是安全的?
- 移动语义和深层/浅层复制之间有什么关系?
- 高CPU使用率,在API桌面复制中获取帧之间具有不同的超时间隔
- r-在Rcpp和C++之间转换矢量(使用Rcpp::as或Rcpp:::wrap)是否会创建一个新的矢量并复制元素
- 是std::memcpy在不同的可复制类型之间的未定义行为
- char 和 char& 之间是否存在相对复制开销差异?
- C++ 复制字符串的指定索引之间的任何子字符串
- 直接列表初始化和复制列表初始化之间的差异
- 在结构之间复制字符数据
- 在'string=string+s1'和"string+=s1"之间移动语义可以保存多少个复制操作?
- 在线程之间复制 std::vector 而不锁定
- 如果值来自成员变量,则复制初始化和参考初始化之间的C 差异
- 如何在不复制数据的情况下在平面数组和多维数组之间进行转换?
- C++复制构造函数和移动语义之间的区别
- 函数参数和临时变量之间复制构造函数的奇怪行为
- 复制构造函数和模板构造函数之间的冲突
- 在派生类之间复制共享变量(浅副本就足够了)
- 支持复制构造的对象和不支持复制构造的对象之间的泛型C++复制