为什么在这种情况下不允许丢弃restrict
限定符?
void func(double * const *q) {
q[0][0] = 10.0;
}
int main(void) {
double a = 5.0;
double * restrict p = &a;
double * restrict const *q = &p;
// GCC: warning: passing argument 1 of 'func' discards 'restrict' qualifier
// from pointer target type [-Werror=discarded-qualifiers]
func(q);
return 0;
}
错误似乎不直观,因为限制指针可以转换为非限制,并且const
这里确保func
不能用非限制替换p
指针。
答案 0 :(得分:0)
所有类型限定符的一般规则是,您可以安全地和隐式地将指针转换为限定指针类型。这由6.3.2.3以及简单赋值6.5.16.1的规则(在参数传递期间适用)保证。这同样适用于所有限定符:const
,volatile
,restrict
和_Atomic
。
这并不意味着你可以走另一条路。你永远不能隐式地删除限定符,你必须使用显式的强制转换。当您这样做时,您将调用实现定义的行为。
在这种情况下,演员阵容非常安全:func((double*const *)q);
。
值得注意的是,restrict
在函数参数上使用时最有意义,并且您从另一个翻译单元调用这些函数。在本地范围内使用restrict
可能没有多大意义,因为编译器可以很容易地推断出表达式中涉及的变量是指向不同的地址还是相同的地址。
总的来说,它是程序员和编译器之间的“契约”,程序员承诺不通过任何其他变量访问指向的数据。然而,程序员可以通过抛弃restrict
来轻松破坏这个合同,然后发生任何事情。