Search code examples
clanguage-lawyerrestrict-qualifier

Inferring non-aliasing solely from restrict pointer parameter declarations


The C language spec (n3096, 6.7.3.1/8) gives the following example

EXAMPLE 2 The function parameter declarations in the following example

void f(int n, int * restrict p, int * restrict q)
{
  while (n-- > 0)
    *p++ = *q++;
}

assert that, during each execution of the function, if an object is accessed through one of the pointer parameters, then it is not also accessed through the other. The translator can make this no-aliasing inference based on the parameter declarations alone, without analyzing the function body.

How can the translator infer this based on the parameter declarations alone?

For example, allow me to massage this example, preserving the parameter declarations, as follows.

int sum;
void f(int n, int * restrict p, int * restrict q)
{
  while (n-- > 0)
    sum += *p++ + *q++;
}

I argue it is now permissible for the same object to be accessed through both p and q, since this object is no longer modified. (Indeed, this seems to be the point of the subsequent EXAMPLE 3 in clause 10.)

My confusion is reinforced in EXAMPLES 5, 6, and 7 (clauses 13, 14, 15). One way to resolve my confusion would be to modify the text in clause 8,

"... if an object is modified and accessed ..."

along with similar changes in the subsequent examples. But to me this seems to change the semantics.


Solution

  • It is a mistake in the example. Instead of saying the declarations assert that “if an object is accessed through one of the pointer parameters,” it should say “if an object is accessed through one of the pointer parameters and is modified during execution of the function.”

    We can tell it is a mistake because the formal definition of restrict, in 6.7.3.1, does not impose any requirements on an object that is not modified (paragraph 4, “If… and X is also modified… then…”), so it is not possible that the declarations assert anything about merely accessing an object (that is accesses that only read the value and do not modify it).