Two pointer expressions alias when they access the same object. Consider `blub`: it saves `*a`, writes through `b`, then reads `*a` again. If the pointers designate different objects, the last read returns the saved value. If both arguments designate the same object, the write through `b` changes what `a` reads—even though `a` points to `const` data. section 12.3
double blub(double const* a, double* b) {
double myA = *a;
*b = 2*myA;
return *a; // May be myA or 2*myA
}
The return expression is deliberately a fresh read: it can yield `myA` or `2*myA`, depending on whether the arguments alias. section 12.3
TAKEAWAY: Apart from character types, C restricts aliasing through pointers with different base types. In the `size_t`/`double` variant, the write through `b` cannot validly change the value read through `a`; forcing overlapping access by a cast can make behavior undefined. Do not use such casts to defeat the compiler’s assumption. section 12.3 section 16.2
Aliasing matters to optimization: when a call might change an object through another pointer, the compiler may have to read that object again. Avoid taking a local variable’s address when it is unnecessary; keeping it inaccessible through other pointers can give the optimizer more freedom. section 12.3 section 16.0
void* memcpy(void*restrict s1, void const*restrict s2, size_t n); void* memmove(void* s1, const void* s2, size_t n);
The declarations contrast `memcpy`, whose `restrict`-qualified arguments require nonoverlapping access, with `memmove`, which permits overlapping objects. section 16.2
For same-type pointers, `restrict` can state an exclusivity requirement that the compiler cannot otherwise infer. It also places a duty on the caller: violating the requirement can make execution fail, and the restriction may not be enforceable at compile time. Use it only when the required access pattern is guaranteed; correctness comes before performance. section 16.2 section 16.5
