2

我正在尝试调整以下版本的stpcpy函数以使用restrict-qualified 指针作为其参数和内部,但我不确定简单地添加限定符是否会导致引入未定义的行为。

#define ALIGN (sizeof(size_t)-1)
#define ONES ((size_t)-1/UCHAR_MAX)
#define HIGHS (ONES * (UCHAR_MAX/2+1))
#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)

char *__stpcpy(char *d, const char *s)
{
        size_t *wd;
        const size_t *ws;

        if (((uintptr_t)s & ALIGN) == ((uintptr_t)d & ALIGN)) {
                for (; (*d=*s) && ((uintptr_t)s & ALIGN); s++, d++);
                if (!*s) return d;
                wd=(void *)d; ws=(const void *)s;
                for (; !HASZERO(*ws); *wd++ = *ws++);
                d=(void *)wd; s=(const void *)ws;
        }
        for (; (*d=*s); s++, d++);

        return d;
}

假设 C99 6.7.3.1 中关于访问对象的规则仅适用于访问的单个对象而不是整个数组,我认为这可能没问题,因为写入的元素只能访问一次,并且只能用于写入。但我restrict在这一点上使用起来很不舒服,不想仅仅依靠我自己的判断。

4

1 回答 1

3

为了符合标准,唯一的限制是所有操纵函数通过指针接收到的任何对象的指针表达式都restrict应该基于该指针。它不需要指针表达式的类型相同。因此,从这个意义上说,通过这些访问对象size_t*并不是违反约束或 UB。

我不确定读取*wd您修改过的对象的一部分的值*d是否不会别名,因为指针类型不同。但正如你所说,你不这样做,所以这应该是安全的。

顺便说一句,代码做了一个不一定可移植的重要假设,即 an 的低位uintptr_t反映了您转​​换为它的指针的对齐属性。这在我们日常使用中遇到的所有架构上可能都是正确的,但标准并不能保证。甚至 C11 也只说了一些关于“字节地址的倍数”的内容,其中没有任何内容可以说明那将是什么。

于 2012-09-04T07:58:50.837 回答