对 C 限制限定符感到困惑

标签 c alias restrict

首先,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 = '\0';
    }
}

最佳答案

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

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

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

关于对 C 限制限定符感到困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42781554/

相关文章:

c - 将指针传递给具有 volatile 成员的结构作为函数参数

sqlite - 在 sqlite3 where 子句中使用列别名

c - C11限制的正式定义与实现是否一致?

sql - SQL Server 中的别名列名

Java:我是否缺少限制模式?我需要仅使用选定的方法来限制实现

mysql - SQL 限制组合集

c++ - 检测 32 位双字 + 双字进位/C++

c - 奇怪的数组字符串输出

c - 从 sublime 2.02 运行 C 程序

mysql - 带有别名的 GROUP BY 子句?