【问题标题】:Are the restrictions of std::copy more relaxed than std::memcopy?std::copy 的限制是否比 std::memcpy 更宽松?
【发布时间】:2013-11-05 02:18:46
【问题描述】:

regardtothe 问题copy vs. memcpy vs memmove(这里有很好的信息,顺便说一句。),我一直在阅读,在我看来,不像 通俗的说法,例如cppreference注意:自从引用此引文后,memcpy 已更改为 memmove。 --

注意事项

在实践中,std::copy 的实现避免了多重赋值 如果值类型为 TriviallyCopyable

-- std::copy(也不是std::copy_backward不能按照memcopy来实现,因为对于std::copy只有目标范围的开头不得落入源范围,但对于memcpy,整个范围不得重叠。

查看 Visual-C++ 的实现(参见 xutility 标头),我们还可以观察到 VC++ 使用 memmove,但那个现在比 std::copy 有更宽松的要求:

...对象可能重叠:复制就像字符一样发生 被复制到一个临时字符数组,然后字符 从数组中复制...

所以看起来用memcpy 来实现std::copy 是不可能的,但是使用memmove 实际上是一种悲观。 (一点点悲观,可能无法衡量,但仍然)

回到问题:我的总结是否正确?这在任何地方都有问题吗? 无论指定什么,是否存在memcpy 的可能实际实现,它也不能满足std::copy 的要求,即是否存在memcpy 实现在范围部分重叠时中断@ 987654327@std::copy?

【问题讨论】:

  • 首先,std::copy 的实现不一定是严格可移植的,并且可以利用memcpy 的实现细节的知识(例如,在重叠区域之间复制实际上是可以的,如只要它们以正确的方式重叠)。其次,即使它选择不这样做,它仍然可以检查范围并在它们不重叠时(即大部分时间)遵循memcpy
  • libc++ 和 stdlibc++ 也调用 memmove,我将 cppreference 上的注释更改为 memmove。

标签: c++ c stl memcpy memmove


【解决方案1】:

如果问题是,是否有可能遇到具有足够未定义行为的高效 memcpy 实现以在重叠范围内不信任它,那么答案是肯定的。 :-)

考虑在 Power(PC) 架构上的 memcpy 的一种可能实现:lmw 指令会将多个连续字从内存加载到连续寄存器中(可以指定为用户定义的范围参数)。 stmw 然后将提供的寄存器范围保存回内存。因此,我们谈论的是在单个 memcpy 迭代期间由 CPU 缓冲的大约 100/200 字节(32b/64b CPU) - 如果目标范围与源数据重叠,大量数据会破坏目标范围,特别是考虑到 CPU 没有做出任何承诺关于各个加载和存储的相对顺序。

【讨论】:

  • 一个编译器怎么样,给定void f(char *p,char*q) { if (p!=q) doSomething();} void g(char *p,char *q) { f(p,q); memcpy(p,q,sizeof *p); } 将推断标准在 p==q 时对 g 的行为没有要求,从而允许调用“doSomething();”是无条件的吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-10
  • 1970-01-01
  • 1970-01-01
  • 2011-11-09
  • 2013-02-05
  • 2012-09-08
  • 2020-08-06
相关资源
最近更新 更多