相关疑难解决方法(0)

为什么对于非TriviallyCopyable的对象,未定义std :: memcpy的行为?

来自http://en.cppreference.com/w/cpp/string/byte/memcpy:

如果对象不是TriviallyCopyable(例如标量,数组,C兼容结构),则行为未定义.

在我的工作中,我们使用std::memcpy了很长时间来按比例交换不是TriviallyCopyable的对象:

void swapMemory(Entity* ePtr1, Entity* ePtr2)
{
   static const int size = sizeof(Entity); 
   char swapBuffer[size];

   memcpy(swapBuffer, ePtr1, size);
   memcpy(ePtr1, ePtr2, size);
   memcpy(ePtr2, swapBuffer, size);
}
Run Code Online (Sandbox Code Playgroud)

从来没有任何问题.

我理解滥用std::memcpy非TriviallyCopyable对象并导致下游的未定义行为是微不足道的.但是,我的问题是:

std::memcpy当与非TriviallyCopyable对象一起使用时,为什么它本身的行为是未定义的?为什么标准认为有必要指定?

UPDATE

http://en.cppreference.com/w/cpp/string/byte/memcpy的内容已经过修改,以回应这篇文章和帖子的答案.目前的描述说:

如果对象不是TriviallyCopyable(例如标量,数组,C兼容结构),则行为是未定义的,除非程序不依赖于目标对象(不运行memcpy)的析构函数的效果和生命周期目标对象(已结束,但未开始memcpy)由其他一些方法启动,例如placement-new.

PS

@Cubbi的评论:

@RSahu如果有东西保证UB下游,它会使整个程序不确定.但我同意在这种情况下似乎可以绕过UB并相应​​地修改cppreference.

c++ memcpy object-lifetime language-lawyer c++11

67
推荐指数
5
解决办法
5355
查看次数

is_trivially_copyable和is_trivially_copy_constructible有什么区别?

什么时候会给出不同的答案,这种差异什么时候会有用呢?

c++ type-traits c++11

23
推荐指数
1
解决办法
3025
查看次数

我可以memcpy()任何具有普通析构函数的类型吗?

确实知道is_pod一个类型的充分条件是memcpy可行的,但has_trivial_destructor 足够用于此目的?如果没有,为什么?

c++ pod memcpy c++11

10
推荐指数
3
解决办法
1190
查看次数