restrict
限定符意味着被调用函数访问传入内存的唯一方法是通过localPtr
该foo
指针;那段记忆没有别名。这可能使优化器能够生成更好的代码,因为它不必担心另一个指针也会改变数据。
在这种情况下,以及在大多数其他情况下,restrict
限定符对您(进行调用的程序员)承担了责任,以确保您遵守“无别名”要求。
上面的代码没有明显的危险。
请注意,大多数情况下,在使用时,参数列表中有多个指针restrict
。从 C 标准,比较:
void *memcpy(void *restrict s1, const void *restrict s2, size_t n);
void *memmove(void *s1, const void *s2, size_t n);
第一个 ( memcpy()
) 表示内存块不能重叠[s1 .. s1+n-1]
;[s2 .. s2+n-1]
如果它们实际上重叠,您将获得未定义的行为。第二个 ( memmove()
) 没有强加该要求。
但不是调用foo()
创建另一个更改数据的指针吗?
是的,不,有点……但大多不是。
in 中的指针foo()
当然是传递给 的bar()
,但是在bar()
运行时,唯一bar()
可以获取内存的方法是通过它传递的指针。因此bar()
,可以在假设它正在使用的内存没有别名的情况下进行编译。
当编译器正在处理foo()
时,它知道(确保)在计算参数之后bar()
和调用函数之前有一个序列点,并且在函数返回时有另一个序列点。它知道数据可能已被修改,bar()
因为它没有被传递const char *
。因此,它将生成代码来解释这些可能性。但是,编译器也知道唯一foo()
可以访问所寻址的内存的方法localPtr
是通过localPtr
(这就是restrict
所说的),并且它可以基于该假设继续进行。
因此,在被调用时存在指针的第二个副本,但它没有以任何方式bar()
违反规则。restrict