You are on page 1of 1

Chapter 14 ■ Translation Details

This file will contain the function code, which will be referenced by every other file, where the function
was not inlined.

■■Semantics change In GCC prior to 4.2.1 the inline keyword had a slightly other meaning. See the post
[14] for an in-depth analysis.

14.5 restrict
restrict is a keyword akin to volatile and const which first appeared in the C99 standard. It is used to
mark pointers and is thus placed to the right of the asterisk, as follows:

int x;
int* restrict p_x = &x;

If we create a restricted pointer to an object, we make a promise that all accesses to this object will pass
through the value of this pointer. A compiler can either ignore this or make use of it for certain optimizations,
which is often possible.
In other words, any write by another pointer will not affect the value stored by a restricted pointer.
Breaking this promise leads to subtle bugs and is a clear case of undefined behavior.
Without restrict, every pointer is a source of possible memory aliasing, when you can access the same
memory cells by using different names for them. Consider a very simple example, shown in Listing 14-18. Is
the body of f equal to *x += 2 * (*add);?

Listing 14-18. restrict_motiv.c


void f(int* x, int* add) {
    *x += *add;
    *x += *add;
}

The answer is, surprisingly, no, they are not equal. What if add and x are pointing to the same address?
In this case, changing *x changes *add as well. So, in case x == add, the function will add *x to *x making it
two times the initial value, and then repeat it making it four times the initial value. However, when x != add,
even if *x == *add the final *x will be three times the initial value.
The compiler is well aware of it, and even with optimizations turned on it will not optimize away two
reads, as shown in Listing 14-19.

Listing 14-19. restrict_motiv_dump.asm


0000000000000000 <f>:
0:   8b 06                     mov   eax,DWORD PTR [rsi]
2:   03 07                     add   eax,DWORD PTR [rdi]
4:   89 07                     mov   DWORD PTR [rdi],eax
6:   03 06                     add   eax,DWORD PTR [rsi]
8:   89 07                     mov   DWORD PTR [rdi],eax
a:   c3                        ret

281

You might also like