【发布时间】:2020-08-12 17:42:52
【问题描述】:
让我们进入代码:
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 等)。
免责声明:是的,我知道...,这很丑陋,但不要问我为什么需要这样做。
【问题讨论】:
-
此代码中唯一的 UB 是
malloc_and_initialize_one_T()返回一个您没有检查的 NULL 指针,或者T具有非 POD 成员或指针成员。除此之外,您根本不需要static_cast,T* this_t = this;工作得很好,因为TCpp派生自T。 -
我同意@RemyLebeau。只要
ptr_t没有任何问题,static_cast、memcpy和free都是安全的。也就是说,malloc_and_initialize_one_T返回一个正确对齐的 + 大小、非空值、T*而T实际上是一个 POD。 -
@LeoCHan @LeoCHan
T可以是 POD,但在复制到其中时仍然存在问题,即,如果它包含作为指针的成员,它们本身就是 POD,或引用。 -
@RemyLebeau 实际上,在我的例子中,“POD”结构确实包含指针,但这种情况是完全可控的。
-
内存复制到可能重叠的子对象(包括基类子对象)是绝对不允许的,因为潜在的填充重用。
标签: c++ c++11 inheritance malloc language-lawyer