对 C 限制限定符感到困惑

Confused about C restrict qualifier

首先,cppreference对restrict有如下说法:

During each execution of a block in which a restricted pointer P is declared (typically each execution of a function body in which P is a function parameter), if some object that is accessible through P (directly or indirectly) is modified, by any means, then all accesses to that object (both reads and writes) in that block must occur through P (directly or indirectly), otherwise the behavior is undefined.

但是在这一段下面写着:

Restricted pointers can be assigned to unrestricted pointers freely, the optimization opportunities remain in place as long as the compiler is able to analyze the code:

void f(int n, float * restrict r, float * restrict s) {
   float * p = r, * q = s; // OK
   while(n-- > 0) *p++ = *q++; // almost certainly optimized just like *r++ = *s++
}

在上面,r[0]是一个对象,可以通过受限指针r访问,它是通过p访问的,这似乎与第一段矛盾(那访问 r[0] 必须仅通过 r) ?

第二个:

Assignment from one restricted pointer to another is undefined behavior, except when assigning from a pointer to an object in some outer block to a pointer in some inner block (including using a restricted pointer argument when calling a function with a restricted pointer parameter) or when returning from a function (and otherwise when the block of the from-pointer ended).

那么,下面的代码可以吗?

void foo(char* restrict a, size_t s)
{
    for(char* restrict aa = a; aa < a + s; ++aa) // Is aa in an inner block?
    {
        *aa = '[=11=]';
    }
}

示例 1 的关键是用于访问 r 指向的底层数组的左值 *p 的地址基于 r。换句话说,它是通过 r 间接 访问。由于 *q 也有其基于 s 的地址,因此所有访问均通过原始受限指针发生,即使是间接访问:此处没有 UB。

示例 2 更为简单。您在原始指针上声明了一个新的受限指针 based。所以也没有UB。但是在示例 2 中,两个受限限定符都没有添加任何值,因为在块内部(foo 函数定义)只使用了一个指针,因为 aa 基于 a.

在示例 1 中,restrict 限定符向编译器声明由 rs 指向的数组不重叠:无法通过 r 访问(直接或间接通过 p) 应该触及 s.

指向的数组