Question

I came across these two sections in C11 standard referring to the restrict qualifier:

1#

6.7.3-8

An object that is accessed through a restrict-qualified pointer has a special association with that pointer. This association, defined in 6.7.3.1 below, requires that all accesses to that object use, directly or indirectly, the value of that particular pointer.135) The intended use of the restrict qualifier (like the register storage class) is to promote optimization, and deleting all instances of the qualifier from all preprocessing translation units composing a conforming program does not change its meaning (i.e., observable behavior).

Can you explain me the meaning of the cursive fragment? In my interpretation, since it doesn't change its meaning, it looks like that the using of restrict is just pointless...

2#

6.7.3.1-6

A translator is free to ignore any or all aliasing implications of uses of restrict.

What might these aliasing implications be? Can you show me some examples?

Was it helpful?

Solution

The cursive statement in the first quote basically said:

  • You may define away the restrict keyword by for example putting a #define restrict line into your code without changing any meaning of your c-code. You code may become a bit slower due to missed optimization, but you will in all cases get the same, deterministic results as if you would have used the restrict keyword.

Second paragraph means that the compiler is free to ignore the restrict keyword. Easy as that.

OTHER TIPS

Restrict is not pointless, it allows the compiler to make optimizations that would not otherwise be allowed if pointer aliasing is a possibility. For example, the following function:

int foo(int *a, int *b)
{
    *a = 5;
    *b = 6;
    return (*a + *b);
}

What does this function return? If you said 11, you're only partly right. It returns 11 unless a == b, in which case it returns 12, or worse, a partially overlaps with b which could be one of several values. To make sure that it behaves correctly, the compiler has to emit code that

1) stores 5 to a
2) stores 6 to b
3) loads a into a temporary register
4) adds the temp and 6
5) returns the sum

If you as a programmer know a == b is never going to happen, you can tell the compiler that you don't want it to worry about this case using the restrict keyword.

int foo(int * restrict a, int * restrict b)

The code that will be generated for this function will be:

1) store 5 to a
2) store 6 to b
3) return 11

The compiler was able to do the optimization because you promised it there will be no aliasing issues. And, according to the standard, if the compiler just chose to ignore the restrict keyword, the code it would generate would just be the conforming (unoptimized) code in the first case which would still work the same way for all instances you care about.

Both paragraphs say that ‛restrict‛ is just a hint for optimizations and that the implementation is free to ignore it.

and deleting all instances of the qualifier from all preprocessing translation units composing a conforming program does not change its meaning (i.e., observable behavior).

It means that in a conforming program, all uses of the restrict keyword respect the rules, so that removing it will not change the result of the program.

Specifically, in a conforming program no parameters passed as restrict pointers will alias other restrict pointers. Otherwise, removing the keyword might change the meaning of the program.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top