对限制限定符的未定义行为感到困惑
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
限定符。
我在 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
限定符。