从这个链接: http://clc-wiki.net/wiki/memmove
#include <stddef.h> /* for size_t */
void *memmove(void *dest, const void *src, size_t n)
{
unsigned char *pd = dest;
const unsigned char *ps = src;
if (__np_anyptrlt(ps, pd))
for (pd += n, ps += n; n--;)
*--pd = *--ps;
else
while(n--)
*pd++ = *ps++;
return dest;
}
使用__np_anyptrlt
是多余的吗?为什么不使用if (ps < pd)
?
答案 0 :(得分:3)
您链接的页面上的注释解释了它:
__ np_anyptrlt(p1,p2):
一个宏或函数,对于任何两个指针p1和p2,__np_anyptrlt(p1,p2)求值为:
如果p1和p2指向同一对象且p1较小,则
- 非零 比p2
如果p1和p2指向同一对象且p1大于p2 ,则- 为零
- 如果指针未指向同一对象或者它们比较相等,则为未指定的整数值。
一个天真的实现是((p1)&lt;(p2)),但是根据标准,6.5.9(N1124编号),当p1和p2没有指向(或者一个成员过去)时,这会导致未定义的行为一个数组对象的结束。这种天真的实现只应由实现者使用,这些实现者可以确保在这些情况下行为总是合理的。在这些情况下,表达式的实际结束值无关紧要,因为对于不同的对象,无论memmove在哪个方向迭代,都不可能破坏内存。
因此,如果您的平台保证指向不同数组的指针之间的比较表现良好,那么使用ps < pd
是唯一安全的。标准说这种比较是未定义的,所以一个无益的编译器可能会创建任何可以执行任何操作的代码(例如崩溃,破坏数据或让恶魔飞出你的鼻子)。
大多数编译器可能会做一些可接受的事情,但您需要查阅特定编译器的文档才能确定。