C++:memcpy 是基于 POD 的子对象 UB 吗?
C++: Is memcpy to POD based sub-object UB?
我们来看代码:
extern "C" {
#include "pod-struct-T.h"
#include "malloc-and-initialize-one-T.h"
}
struct TCpp : T
{
TCpp()
{
T* ptr_t = malloc_and_initialize_one_T();
T* this_t = static_cast<T*>(this);
std::memcpy(this_t, ptr_t, sizeof(T));
free(ptr_t);
}
};
这段代码中有多少个 UB(对于 C++03 和 C++11;或者对于 C++20,如果在其重新访问内存模型后某些内容发生了变化)或这样做 memcpy
就好了吗?如果是 UB,它是否至少可以在主要编译器之间移植? (gcc、clang、intel 等)。
免责声明:是的,我知道...,这很丑陋,但不要问我为什么需要这样做。
这条规则非常明确。 [basic.types]/3(强调,省略脚注):
For any trivially copyable type T
, if two pointers to T
point to
distinct T
objects obj1
and obj2
, where neither obj1
nor obj2
is a
potentially-overlapping subobject, if the underlying bytes
([intro.memory]) making up obj1
are copied into obj2
, obj2
shall
subsequently hold the same value as obj1
.
Base-class subobjects are potentially-overlapping subobjects. 由此可见,如果您 memcpy
进入 base-class 子对象,则标准没有定义结果值是什么。
简单赋值有什么问题?
我们来看代码:
extern "C" {
#include "pod-struct-T.h"
#include "malloc-and-initialize-one-T.h"
}
struct TCpp : T
{
TCpp()
{
T* ptr_t = malloc_and_initialize_one_T();
T* this_t = static_cast<T*>(this);
std::memcpy(this_t, ptr_t, sizeof(T));
free(ptr_t);
}
};
这段代码中有多少个 UB(对于 C++03 和 C++11;或者对于 C++20,如果在其重新访问内存模型后某些内容发生了变化)或这样做 memcpy
就好了吗?如果是 UB,它是否至少可以在主要编译器之间移植? (gcc、clang、intel 等)。
免责声明:是的,我知道...,这很丑陋,但不要问我为什么需要这样做。
这条规则非常明确。 [basic.types]/3(强调,省略脚注):
For any trivially copyable type
T
, if two pointers toT
point to distinctT
objectsobj1
andobj2
, where neitherobj1
norobj2
is a potentially-overlapping subobject, if the underlying bytes ([intro.memory]) making upobj1
are copied intoobj2
,obj2
shall subsequently hold the same value asobj1
.
Base-class subobjects are potentially-overlapping subobjects. 由此可见,如果您 memcpy
进入 base-class 子对象,则标准没有定义结果值是什么。
简单赋值有什么问题?