首先,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
限定符向编译器声明 r
和 s
指向的数组不重叠:不能通过r
(直接或间接通过p
)应该触及s
指向的数组。
关于对 C 限制限定符感到困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42781554/