ericw31415
ericw31415

Reputation: 495

Can the `restrict` keyword be used in the function definition only?

I am wondering if it is possible to include the restrict keyword only in the function definition and not in the function declaration like so:

void foo(char *bar);

void foo(char * restrict bar)
{
    // do something
}

Since foo only takes one argument, any pointer aliasing would have to take place inside foo. There would be no need for the person calling the function to know about the restrict modifier. Would it be fine to omit the keyword in only the function declaration, just like with const?

Upvotes: 7

Views: 878

Answers (2)

Michel
Michel

Reputation: 339

The next C99 source code can show you that the output of the program depends on restrict :

__attribute__((noinline))
int process(const int * restrict const a, int * const b) {
    *b /= (*a + 1) ;
    return *a + *b ;
}

int main(void) {
    int data[2] = {1, 2};
    return process(&data[0], &data[0]);
}

The software terminates with code 1 using restrict and 0 without restrict qualifier.
The compilation is done with gcc -std=c99 -Wall -pedantic -O3 main.c.
The flag -O1 do the job too.

And so on.

Upvotes: 0

Eric Postpischil
Eric Postpischil

Reputation: 223254

You may use restrict on parameters in function declarations whether they are definitions or not, as it is allowed by the C grammar and there is no rule against it. However, they have no effect to the compiler in declarations that are not definitions. This is because 6.5.2.2 7 says qualifiers are removed when passing arguments to functions with prototypes:

… the arguments are implicitly converted, as if by assignment, to the types of the corresponding parameters, taking the type of each parameter to be the unqualified version of its declared type.

Thus, if a function declaration has a parameter of type int * restrict a, whatever argument you pass is converted to the unqualified type, int *.

Further, two otherwise identical function declarations are compatible even if the qualifiers on parameters are changed, because C 2018 6.7.6.3 15 says:

… (In the determination of type compatibility and of a composite type, … each parameter declared with qualified type is taken as having the unqualified version of its declared type.)

However, this applies only to the parameter itself. The parameter is not affected by a restrict that qualifies it. But it can point to a pointer that is restrict-qualified. For example, void foo(void * restrict *a); and void foo(void **a); declare different function types.

Although qualifiers on parameters in declarations have no effect to the compiler, they can signal to humans that the arguments are expected to conform to the restriction. Inside the function definition, the parameter is restrict-qualified, and anybody calling the function should respect that.

Upvotes: 10

Related Questions