【发布时间】:2018-10-27 22:58:51
【问题描述】:
假设我们有一个函数声明,我们无法访问它的定义:
void f(int * restrict p, int * restrict q, int * restrict r);
由于我们不知道如何访问指针,我们无法知道调用是否会触发未定义的行为——即使我们传递相同的指针,如 6.7.3.1.10 中的示例解释:
函数参数声明:
void h(int n, int * restrict p, int * restrict q, int * restrict r) { int i; for (i = 0; i < n; i++) p[i] = q[i] + r[i]; }说明如何通过两个受限指针对未修改的对象进行别名。特别是,如果
a和b是不相交的数组,则h(100, a, b, b)形式的调用具有定义的行为,因为数组b未在函数h中修改。
因此,restrict 在这些情况下是否是多余的,除非我们对函数有更多了解,除非作为调用者的提示/注释?
例如,让我们从标准库中获取sprintf (7.21.6.6):
概要
#include <stdio.h> int sprintf(char * restrict s, const char * restrict format, ...);说明
sprintf函数等效于fprintf,除了输出写入数组(由参数s指定)而不是流。 (...)
从概要和描述的第一句话,我们知道s 将被写入,s 是一个受限指针。因此,我们是否可以假设(无需进一步阅读)这样的调用:
char s[4];
sprintf(s, "%s", s);
会触发未定义的行为吗?
-
如果是,那么:
sprintf的描述的最后一句话是多余的(即使澄清)?如果复制发生在重叠的对象之间,则行为未定义。
如果不是,那么反过来:
restrict限定符是否是多余的,因为描述实际上是让我们知道什么是未定义的行为?
【问题讨论】:
标签: c language-lawyer c99 c11 restrict