C语言 ' restrict '关键字只能在函数定义中使用吗?



我想知道是否有可能仅在函数定义中包含restrict关键字,而不是在函数声明中,如:

void foo(char *bar);
void foo(char * restrict bar)
{
// do something
}

由于foo只接受一个参数,任何指针混叠都必须在foo内部进行。调用函数的人不需要知道restrict修饰符。像const一样,只在函数声明中省略关键字可以吗?

您可以在函数声明中的参数上使用restrict,无论它们是否是定义,因为它是C语法允许的,并且没有规则反对它。但是,在非定义的声明中,它们对编译器没有影响。这是因为6.5.2.2 7规定,当向带有原型的函数传递参数时,将删除限定符:

…实参隐式地转换为对应形参的类型,就像通过赋值一样,将每个形参的类型作为其声明类型的非限定版本。

因此,如果函数声明具有int * restrict a类型的形参,则传递的任何实参都将转换为非限定类型int *

此外,即使参数上的限定符改变了,两个其他相同的函数声明也是兼容的,因为C 2018 6.7.6.3 15说:

…(在确定类型兼容性和复合类型时,…每个用限定类型声明的形参都被视为具有其声明类型的非限定版本。)

但是,这只适用于形参本身。该参数不受限定它的restrict的影响。但是它可以指向一个受限制限定的指针。例如,void foo(void * restrict *a);void foo(void **a);声明不同的函数类型。

尽管声明中形参上的限定符对编译器没有影响,但它们可以向人们发出信号,表明实参应该符合限制。在函数定义内部,形参是有限制限定的,任何调用函数的人都应该尊重这一点。

下面的C99源代码可以向您展示程序的输出取决于On restrict:

__attribute__((noinline))
int process(const int * restrict const a, int * const b) {
*b /= (*a + 1) ;
return *a + *b ;
}
int main(void) {
int data[2] = {1, 2};
return process(&data[0], &data[0]);
}

使用restrict,软件以代码1终止and 0 withoutrestrict限定符。
编译是用gcc -std=c99 -Wall -pedantic -O3 main.c完成的。
标志-O1也完成了这个工作。

等等

最新更新