在指向同一数组的两个指针上使用 restrict

Usage of restrict on two pointers pointing to same array

我很难在 C 中正确使用 restrict 关键字。我编写了这个函数来就地反转字符串:

void my_strrev(char *restrict str, const size_t len) {
    char *restrict strr = str + len - 1;
    char temp;
    while (str < strr) {
        temp = *str;
        *str++ = *strr;
        *strr-- = temp;
    }
}

在这里,虽然 strstrr 都指向同一个数组,但我使用这些指针来访问单个字符,并且它们从不指向相同的字符。因此我认为这是 restrict 的正确用法。当我 运行 这个程序只有很少的样本输入时,我也得到了预期的输出。但我不确定我对 restrict 的用法。所以,如果我做错了,请纠正我。

restrict 几乎只有一个用途——程序员与编译器签订的合同说“我保证我不会将指向相同数据的参数传递给具有外部链接的此函数。 “时至今日,这主要还是基于编译器对程序员的信任,而不是编译器在程序员“违约”时给出诊断信息。

如果编译器可以假设程序员信守承诺,它可以进行优化:

  • 可以假设传递给函数的缓冲区不会重叠——不需要临时存储。 (例如,参见 memcpymemmove。)
  • 可以假设不同的指针参数不是彼此的别名,指向相同的数据。 (如果你有一个 char* 和一个 int* 参数,这是可能的。)
  • 可以假定指针参数不会修改函数使用的任何外部链接资源(“全局变量”),但所有对指针指向的内容的访问都是通过该指针发生的。

对局部指针变量使用restrict意义不大,因为它与上述任何情况都不相关。它会编译,但使用它不会有任何好处。据我所知,如果您不恰当地使用 restrict 指针,目前任何主流编译器都没有提供额外的诊断。

restrict 本质上说,函数通过该指针访问的所有内存都不会以任何其他方式访问,即,也不会通过另一个参数或以任何其他方式加载的指针或通过外部对象访问。

将参数赋给其他变量并使用这些变量访问内存是可以的。这些访问仍然来自原始指针。它们不是来自不同的参数或其他来源。