`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); 声明不同的函数类型。

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