对限制限定符的未定义行为感到困惑

Confusion about undefined behaviour for restrict qualifier

我在 cppreference 上看到了下面的例子。

void f(int n, int * restrict p, int * restrict q)
{
    while(n-- > 0)
        *p++ = *q++; // none of the objects modified through *p is the same
                     // as any of the objects read through *q
                     // compiler free to optimize, vectorize, page map, etc.
}
void g(void)
{
    extern int d[100];
    f(50, d + 50, d); // OK
    f(50, d + 1, d); // Undefined behavior: d[1] is accessed through both p and q in f
}

在那个例子中,调用 f(50, d + 50, d); 就可以了。

但是,我不明白,调用f(50, d + 1, d);是未定义的行为。为什么?

指针上的 restrict 限定符意味着在该指针的生命周期内,通过修改的指针访问的任何对象都不会通过其他指针访问。换句话说,当一个对象通过指针 p 访问并在 p 的范围内被修改时,那么它只能在该范围内通过 p 访问。违反此约束会导致未定义的行为。

f(50, d + 50, d);中,p将用于修改d[50]直至d[99],而q将用于访问d[0] 最多 d[49]。没有重叠所以一切都很好。

f(50, d + 1, d);中,p将用于修改d[1]直到d[50],而q将用于访问d[0] 最多 d[49]。由于某些元素(例如 d[1])通过 p 修改并通过 q 读取,这违反了 restrict 限定符。