在memmove中使用__np_anyptrlt?

ech*_*cho 2 c memmove

通过此链接: 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;
}
Run Code Online (Sandbox Code Playgroud)

使用是否__np_anyptrlt多余?为什么不直接使用if (ps < pd)呢?

Blc*_*ght 5

您链接的页面上的注释对此进行了解释:

__np_anyptrlt(p1,p2):

一个宏或函数,对于任意两个指针 p1 和 p2,__np_anyptrlt(p1,p2) 的计算结果为:

  • 如果 p1 和 p2 指向同一对象且 p1 小于 p2,则非零
  • 如果 p1 和 p2 指向同一对象且 p1 大于 p2,则为零
  • 如果指针未指向同一对象或它们比较相等,则为未指定的整数值。

一种幼稚的实现是 ((p1) < (p2)),但根据标准 6.5.9(N1124 编号),当 p1 和 p2 不指向内部(或超出末尾的一个成员)时,这会导致未定义的行为单个数组对象。这种幼稚的实现只能由能够确保在这些情况下行为始终合理的实现者使用。在这些情况下,表达式的实际最终值并不重要,因为对于不同的对象,无论 memmove 在哪个方向迭代,都不可能损坏内存。

ps < pd因此,只有当您的平台保证不同数组的指针之间的比较行为正常时,才可以安全使用。该标准规定,此类比较是未定义的,因此无用的编译器可能会创建执行任何操作的代码(例如崩溃、损坏数据或让恶魔从你的鼻子里飞出来)。

大多数编译器可能会做一些可接受的事情,但您需要查阅特定编译器的文档才能确定。