Suppose we have a function declaration for which we do not have access to its definition:
void f(int * restrict p, int * restrict q, int * restrict r);
Since we do not know how the pointers will be accessed, we cannot know if a call will trigger undefined behavior or not -- even if we are passing the same pointer, like the example at 6.7.3.1.10 explains:
The function parameter declarations:
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]; }
illustrate how an unmodified object can be aliased through two restricted pointers. In particular, if
a
andb
are disjoint arrays, a call of the formh(100, a, b, b)
has defined behavior, because arrayb
is not modified within functionh
.
Therefore, is restrict
superfluous in these cases, except as a hint/annotation for callers, unless we know something more about the function?
For instance, let's take sprintf
(7.21.6.6) from the standard library:
Synopsis
#include <stdio.h> int sprintf(char * restrict s, const char * restrict format, ...);
Description
The
sprintf
function is equivalent tofprintf
, except that the output is written into an array (specified by the arguments
) rather than to a stream. (...)
From the synopsis and the first sentence of the description, we know that s
will be written to and that s
is a restricted pointer. Therefore, can we already assume (without reading further) that a call like:
char s[4];
sprintf(s, "%s", s);
will trigger undefined behavior?
If yes, then: is the last sentence of
sprintf
's description superfluous (even if clarifying)?If copying takes place between objects that overlap, the behavior is undefined.
If not, then, the other way around: is the
restrict
qualifier superfluous since the description is the one that is actually letting us know what will be undefined behavior?