`restrict`是否会影响传递指针的别名,而不是彼此

sup*_*cat 4 c restrict strict-aliasing language-lawyer restrict-qualifier

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

void foo1(int * restrict a, int * restrict b) {
  (*a)++; (*b)++; (*b)+=(*a);
}
Run Code Online (Sandbox Code Playgroud)

编译器有权假设写入(*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;
}
Run Code Online (Sandbox Code Playgroud)

是否需要编译器预期增加*q,调用foo2a()foo2b()可能都会受到干扰x,并且调用可能对" x和"的值"感兴趣" *q?编译器是否需要假设调用foo2a()可能持有其参数 - 即使它被标记restrict,这样foo2b()可以修改z

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

Jen*_*edt 5

在标题中回答你的问题:是的.一个restrict合格的指针意味着你保证,有关整个对象只能通过该指针访问孤独.这也意味着它不能与相同类型的文件范围对象进行别名,例如

对于其余的问题,你正在混合的东西.restrict绝不是来电者的保证.调用者甚至没有"看到" restrict关键字,类型限定不是界面的一部分.因此,从调用返回时文件范围变量是否可能已更改与此无关restrict.

restrict 只是保证呼叫者给予被叫者,然后可以在内部使用该信息进行优化.