4

添加到 C99 中的关键字的主要用途之一restrict是允许编译器将某些内容加载到寄存器中,并假设该寄存器将镜像由此加载的变量的状态。给定

void foo1(int * restrict a, int * restrict b) {
  (*a)++; (*b)++; (*b)+=(*a);
}

编译器有权假设写入(*b)不会受到影响(*a),从而避免(*a)在它之后重新加载。restrict对混叠有任何其他影响吗?例如,给定:

extern void foo2a(int * restrict q);
extern void foo2b(void);
int x;
int foo2(restrict int *q) {
  int z=x;
  x++; *q++; x++;
  foo2a(&z);
  x++; *q++; z++;
  foo2b();
  x++; *q++; z++;
  return x+(*q)+z;
}

编译器是否需要预测 的增量,以及对and*q的调用都可能受到干扰,并且调用可能对and的值“感兴趣” ?是否需要编译器假设调用可能已经持久化了它的参数——即使它被标记了,这样可以修改?foo2a()foo2b()xx*qfoo2a()restrictfoo2b()z

如果编译器需要在最坏情况的假设下运行,尽管有restrict关键字,是否有任何方法可以授予编译器权限以忽略在函数调用之前存储对某些变量的任何更改并在下次重新加载它的任何正常义务需要吗?

4

1 回答 1

6

仅在标题中回答您的问题:是的。合格的restrict指针意味着您保证整个对象只能通过该指针单独访问。这也意味着它不能使用相同类型的文件范围对象进行别名,例如

对于问题的其余部分,您正在混合内容。restrict绝不是来电者的保证。调用者甚至没有“看到”restrict关键字,类型限定不是接口的一部分。因此,从调用返回时文件范围变量是否可能已更改与restrict.

restrict只是调用者向被调用者提供的保证,被调用者可以在内部使用该信息进行优化。

于 2015-04-28T20:18:32.977 回答