restrict 关键字对唯一指针类型的参数没有意义吗?
Is the restrict keyword meaningless on parameters of unique pointer types?
我注意到在我们的一个遗留项目中大量使用了 restrict
关键字。
我理解 restrict
的基本原理,但我质疑它在应用于其中一些功能时是否有用。
举下面两个例子:
void funcA(int *restrict i){
// ...
}
void funcB(int *restrict i, float *restrict f){
// ...
}
int main(){
int i = 1;
float f = 3.14;
funcA(&i);
funcB(&i,&f);
}
是否有任何正当理由可以用 restrict
标记 funcA
和 funcB
的参数?
funcA
只需要 1 个参数。它怎么可能和其他东西有相同的地址呢?
funcB
接受不同类型的参数。如果它们是同一个地址,那不是已经违反了严格的别名规则吗?
restrict
对于 single-pointer-parameter 函数 而不是 没有意义。
restrict
关键字是一个意图声明,用于改进优化。这意味着给定指针指向的对象在(在这种情况下)函数参数的生命周期内不会被任何其他东西指向。
你没有显示函数的代码,所以里面可能有静态变量。 Restrict 保证那些静态变量不会给参数起别名。
您的示例中可能没有显示全局变量。 Restrict 保证那些全局变量不会给参数起别名。
实际上,您是对的:很可能有人对 restrict 有点疯狂。但是 restrict 不是 意味着 "this parameter and that parameter"。意思是"this pointer and any other pointer".
给定函数:
int foo(int *restrict p)
{
*p = 3;
bar();
return *p;
}
编译器可以相当容易地看到——因为 restrict
限定符——bar()
没有合法的方式可以访问 *p
。从而可以将上面的代码优化成:
int foo(int *restrict p)
{
bar();
*p = 3;
return 3;
}
并且它可以执行此类优化 而无需了解任何有关 bar()
的信息。在没有限定符的情况下,编译器将不得不考虑调用者可能具有的可能性,例如传递了由 bar()
修改的全局 int
的地址,但由于 restrict
编译器不必担心这一点。
我注意到在我们的一个遗留项目中大量使用了 restrict
关键字。
我理解 restrict
的基本原理,但我质疑它在应用于其中一些功能时是否有用。
举下面两个例子:
void funcA(int *restrict i){
// ...
}
void funcB(int *restrict i, float *restrict f){
// ...
}
int main(){
int i = 1;
float f = 3.14;
funcA(&i);
funcB(&i,&f);
}
是否有任何正当理由可以用 restrict
标记 funcA
和 funcB
的参数?
funcA
只需要 1 个参数。它怎么可能和其他东西有相同的地址呢?
funcB
接受不同类型的参数。如果它们是同一个地址,那不是已经违反了严格的别名规则吗?
restrict
对于 single-pointer-parameter 函数 而不是 没有意义。
restrict
关键字是一个意图声明,用于改进优化。这意味着给定指针指向的对象在(在这种情况下)函数参数的生命周期内不会被任何其他东西指向。
你没有显示函数的代码,所以里面可能有静态变量。 Restrict 保证那些静态变量不会给参数起别名。
您的示例中可能没有显示全局变量。 Restrict 保证那些全局变量不会给参数起别名。
实际上,您是对的:很可能有人对 restrict 有点疯狂。但是 restrict 不是 意味着 "this parameter and that parameter"。意思是"this pointer and any other pointer".
给定函数:
int foo(int *restrict p)
{
*p = 3;
bar();
return *p;
}
编译器可以相当容易地看到——因为 restrict
限定符——bar()
没有合法的方式可以访问 *p
。从而可以将上面的代码优化成:
int foo(int *restrict p)
{
bar();
*p = 3;
return 3;
}
并且它可以执行此类优化 而无需了解任何有关 bar()
的信息。在没有限定符的情况下,编译器将不得不考虑调用者可能具有的可能性,例如传递了由 bar()
修改的全局 int
的地址,但由于 restrict
编译器不必担心这一点。