Occasion
While there have been several requests in the past about the use and purpose of the pointer qualifier __restrict, I'll try to explain it within this document. In case you neglect any optimization purpose of C programms, you might want to keep reading on though.
Description
__restrict is a type qualifier and can only be used in conjunction with pointers. Its intention is to influence compiler optimizations. As you will see, it's an useful flag in large programms with many dereferences to certain values.
For a better understanding, we have to consider the way compiler optimizations are done. Normally, the compiler has to dereference a pointer everytime it wants to access - this, to ensure the value's correctness. The compiler has to assume the possibility of manipulation through other pointers referring to the same address (aliases). By using the __restrict qualifier, you assert the uniqueness of a pointer pointing to a specific address. The compiler relies on it and optimizes the latency of dereference by reading the value once and storing it internally. Next time, when neccessary, it reads the value from cache instead of dereferencing it again, which reduces the access time enormously. The validity of the qualifier is limited by local block boundaries (block scope).
This was the theory, now follows a practical code snippet:
float x[100];
float *c;
void foo(int n, float *__restrict a, float * const b)
{
int i;
for ( i=0; i<n; i++ )
a[i] = b[i] + c[i];
}
void bar(void)
{
float d[100], e[100];
c = x; foo(100, d, e); /* Behavior defined. */
foo( 50, d, d+50); /* Behavior defined. */
foo( 99, d+1, d); /* Behavior undefined. */
c = d; foo( 99, d+1, e); /* Behavior undefined. */
foo( 99, e, d+1); /* Behavior defined. */
}
If you try to assign an unique pointer to another, the behavior is undefined.
int *__restrict p1, *__restrict p2;
void foo2(int *__restrict q1, *__restrict q2)
{
q1 = p1; /* Valid behavior */
p1 = p2; /* Behavior undefined */
p1 = q1; /* Behavior undefined */
q1 = q2; /* Behavior undefined */
{
int *__restrict r1, *__restrict r2;
...
r1 = p1; /* Valid behavior */
r1 = q1; /* Valid behavior */
r1 = r2; /* Behavior undefined */
q1 = r1; /* Behavior undefined */
p1 = r1; /* Behavior undefined */
...
}
}
Permanence of strings
You might have been in the situation where given strings were constant and have been referred by an unique pointer. It's a good idea to tell the compiler to optimize the access:
FILE *fopen(const char *__restrict filename, const char *__restrict mode);
Have a look into your standard C library (libc), you'll find such declarations in plenty.
C89 and C99
The __restrict qualifier has been introduced in the C99 specification (restrict). For compatibility with the older C89, you better use the notation used above.