3

The whole point of restrict is to promise accesses through one pointer don't alias another. That said, there are examples where overlapping memory addresses wouldn't imply aliasing. For example:

int* arr_ptr0 = &arr[0];
int* arr_ptr1 = &arr[1];
for (int i=0;i<10;++i) {
    *arr_ptr0 = *arr_ptr1;
    arr_ptr0 += 2;
    arr_ptr1 += 2;
}

The thing is, these pointers actually do point to overlapping memory! For this particular example, guides like this say, e.g.:

It is valid . . . to point into the same array object, provided the range of elements accessed through one of the pointers does not overlap with the range of elements accessed through the other pointer.

My question is: What granularity is "elements"?

For example, suppose I have an array of type struct Foo. Do I really need to ensure that I don't access the same range of elements (Foos), even if the parts I access are disjoint? Here's a simple, scalar example:

struct Foo { int i; float f; };
void f(struct Foo*restrict foo0, struct Foo*restrict foo1) {
    foo0->i = 6;
    foo1->f = 19.0f;
}
void g(struct Foo* foo) {
    f(foo,foo); /* problem? */
}

You can run into similar issues with pointers to different types (e.g. char vs. int), but perhaps the structure example above is more clear.

4

2 回答 2

1

标准的相关文本是6.7.3.1 限制的正式定义

1 令 D 是一个普通标识符的声明,它提供了一种将对象 P 指定为指向类型 T 的限制限定指针的方法。

2 如果 D 出现在一个块内并且没有存储类 extern,则让 B 表示该块。如果 D 出现在函数定义的参数声明列表中,则让 B 表示关联的块。否则,让 B 表示 main 块(或在独立环境中程序启动时调用的任何函数块)。

3 在下文中,如果(在对 E 求值之前执行 B 的某个序列点)修改 P 以指向它之前所在的数组对象的副本,则称指针表达式 E 基于对象 P指向会改变 E.137 的值)请注意,“基于”仅针对具有指针类型的表达式定义。

4 在B的每次执行过程中,令L为基于P的任何具有&L的左值。如果L用于访问它指定的对象X的值,并且X也被修改(通过任何方式),那么以下要求apply:T 不应是 const 限定的。用于访问 X 值的每个其他左值也应具有基于 P 的地址。就本子条款而言,修改 X 的每个访问也应被视为修改 P。如果为 P 分配了一个指针表达式 E 的值,该指针表达式 E 基于与块 B2 关联的另一个受限指针对象 P2,则 B2 的执行应在 B 的执行之前开始,或者 B2 的执行应在任务。如果不满足这些要求,则行为未定义。

5 这里 B 的执行是指程序执行的一部分,对应于标量类型的对象的生命周期和与 B 关联的自动存储持续时间。

根据我对标准的阅读,您的第一个示例(交错数组)完全有效。

结构的第二个例子不太清楚,它取决于使用->运算符(你写.但意味着->)是否意味着foo0(或)是“用于访问它指定的对象的值”。我不清楚这一点,因为该结构不用作值;只有它的成员是。foo1*foo0foo1

于 2014-09-19T20:16:37.867 回答
-1

restrict关键字是对编译器的严格建议,即应用程序不会在类型限定范围内通过另一个不是从它派生的指针修改相同的地址。

不过,实际上没有什么能限制应用程序这样做。但是,可以安全地假设通过restrict限定指针以外的东西修改通过限定指针访问的地址restrict将导致未定义的行为(当心龙)。

于 2014-09-19T20:07:45.413 回答