restrict and Pointer Aliasing
restrict and Pointer Aliasing
Thesis
restrict (C99) is a promise you make to the compiler: for the lifetime of that pointer, no other pointer in the same scope will access the same object. That promise unlocks vectorisation and load/store reordering. Break the promise and you get silent wrong answers — not a warning.
Mental model
add(n, out, a, b) with restrict on all three
→ compiler may assume out[i] is never a[j] or b[j]
→ safe to keep a[i], b[i] in registers across the store to out[i]
Without restrict, a legal (if pathological) call is add(n, a, a, b) where stores to out change later loads from a.
Worked example
Verified with GCC 14.2 -O3 -std=c11.
/* restrict.c — fragment */
void add_restrict(size_t n, double *restrict out,
const double *restrict a, const double *restrict b) {
for (size_t i = 0; i < n; i++) out[i] = a[i] + b[i];
}
void add_alias(size_t n, double *out, const double *a, const double *b) {
for (size_t i = 0; i < n; i++) out[i] = a[i] + b[i];
}A microbenchmark on this box (n=1<<22, 50 repeats, disjoint buffers) printed:
n=4194304 restrict_ms=16.66 alias_ms=6.76 out0=3.0
Treat microbenchmarks carefully: both versions already vectorise at -O3 when buffers do not alias, so wall-clock can go either way depending on cache state. The value of restrict is the permission it gives the optimiser, visible in the generated assembly (objdump -d) more reliably than in a single timing run.
Trap
Lying with restrict. If out overlaps a, the compiler may emit code that is wrong for that call. Never slap restrict on API pointers “for speed” unless the contract forbids overlap (document it).
Boring rule
Use restrict on hot kernels where the contract is “distinct buffers”, document that contract, and prefer sanitizers / tests with deliberate overlap to catch misuse. Do not use it as a general style pepper.
Try this
- Compare
add_restrictvsadd_aliasassembly at-O3withobjdump -d. - Call
add_restrict(n, a+1, a, b)(overlap) and observe wrong results under optimisation. - Read how
memcpyvsmemmoverelate to the same aliasing idea.
Sources
- ISO/IEC 9899:1999 §6.7.3 (
restrict) - GCC manual: Restricted Pointers