I came to know restrict keyword in C recently, and would write down my understanding of it.

The example on its wiki page is a bit misleading, for restrict for the third argument, i.e. val, is not needed.

For a memory pointed by a restrict pointer, if it’s modified, the modification must have been done through the restrict pointer, otherwise, the behavior is undefined.

One could understand it as linear type after the modification. (Note: alias could happen if no modification is performed.)

Let’s examine the generated assembly code:

void updatePtrs(size_t *ptrA, size_t *ptrB, size_t *val)
{
  *ptrA += *val;
  *ptrB += *val;
}

Get the assembly code using clang -S -O test.c:

updatePtrs:                             # @updatePtrs
    .cfi_startproc
# BB#0:
    movq    (%rdx), %rax
    addq    %rax, (%rdi)
    movq    (%rdx), %rax
    addq    %rax, (%rsi)
    retq

Here, we could see that (%rdx) needs to be loaded twice for the possible aliasing.

void updatePtrs(size_t * restrict ptrA, size_t * restrict ptrB, size_t *val)
{
  *ptrA += *val;
  *ptrB += *val;
}

Get the assembly code using clang -S -O test.c:

updatePtrs:                             # @updatePtrs
    .cfi_startproc
# BB#0:
    movq    (%rdx), %rax
    addq    %rax, (%rdi)
    addq    %rax, (%rsi)
    retq

Since both *ptrA and *ptrB are mutated, and have restrict modifier, they have effective linear type, so no aliasing, and *val don’t need to be reloaded. (Note the lacking of restrict keyword for val.)

Reference

c11 standard