Two pointers, one object?
Consider a function that saves `*a`, assigns `2 * saved` to `*b`, then returns `*a`. If `a` and `b` point to distinct objects, the returned value is the saved value. If both point to the same object, writing through `b` also changes what `a` sees, so the returned value is twice the saved value. Declaring `a` as `double const*` does not rule out that change through `b`. section 12.3
1 double blub(double const* a, double* b);
2
3 int main(void) {
4 double c = 35;
5 double d = 3.5;
6 printf("blub is %g\n", blub(&c, &d));
7 printf("after blub the sum is %g\n", c + d);
8 }1 double blub(double const* a, double* b) {
2 double myA = *a;
3 *b = 2*myA;
4 return *a; // May be myA or 2*myA
5 }
!@%STYLE%@!
{"css":"{\"css\": \"font-weight: bold;\"}","target":"[[{\"line\":0,\"ch\":0},{\"line\":0,\"ch\":1}],[{\"line\":7,\"ch\":5},{\"line\":7,\"ch\":6}],[{\"line\":0,\"ch\":4},{\"line\":0,\"ch\":10}],[{\"line\":3,\"ch\":6},{\"line\":3,\"ch\":12}],[{\"line\":4,\"ch\":6},{\"line\":4,\"ch\":12}],[{\"line\":7,\"ch\":9},{\"line\":7,\"ch\":15}],[{\"line\":8,\"ch\":6},{\"line\":8,\"ch\":12}],[{\"line\":0,\"ch\":16},{\"line\":0,\"ch\":28}],[{\"line\":7,\"ch\":21},{\"line\":7,\"ch\":33}],[{\"line\":0,\"ch\":4},{\"line\":0,\"ch\":10}],[{\"line\":3,\"ch\":6},{\"line\":3,\"ch\":12}],[{\"line\":4,\"ch\":6},{\"line\":4,\"ch\":12}],[{\"line\":7,\"ch\":9},{\"line\":7,\"ch\":15}],[{\"line\":8,\"ch\":6},{\"line\":8,\"ch\":12}],[{\"line\":1,\"ch\":0},{\"line\":1,\"ch\":1}],[{\"line\":8,\"ch\":0},{\"line\":8,\"ch\":1}],[{\"line\":9,\"ch\":11},{\"line\":9,\"ch\":12}],[{\"line\":10,\"ch\":39},{\"line\":10,\"ch\":40}],[{\"line\":2,\"ch\":0},{\"line\":2,\"ch\":1}],[{\"line\":3,\"ch\":17},{\"line\":3,\"ch\":18}],[{\"line\":4,\"ch\":17},{\"line\":4,\"ch\":18}],[{\"line\":9,\"ch\":0},{\"line\":9,\"ch\":1}],[{\"line\":2,\"ch\":4},{\"line\":2,\"ch\":7}],[{\"line\":5,\"ch\":8},{\"line\":5,\"ch\":11}],[{\"line\":6,\"ch\":8},{\"line\":6,\"ch\":11}],[{\"line\":2,\"ch\":8},{\"line\":2,\"ch\":12}],[{\"line\":2,\"ch\":13},{\"line\":2,\"ch\":17}],[{\"line\":3,\"ch\":0},{\"line\":3,\"ch\":1}],[{\"line\":10,\"ch\":0},{\"line\":10,\"ch\":1}],[{\"line\":0,\"ch\":4},{\"line\":0,\"ch\":10}],[{\"line\":3,\"ch\":6},{\"line\":3,\"ch\":12}],[{\"line\":4,\"ch\":6},{\"line\":4,\"ch\":12}],[{\"line\":7,\"ch\":9},{\"line\":7,\"ch\":15}],[{\"line\":8,\"ch\":6},{\"line\":8,\"ch\":12}],[{\"line\":3,\"ch\":18},{\"line\":3,\"ch\":19}],[{\"line\":4,\"ch\":0},{\"line\":4,\"ch\":1}],[{\"line\":11,\"ch\":0},{\"line\":11,\"ch\":1}],[{\"line\":0,\"ch\":4},{\"line\":0,\"ch\":10}],[{\"line\":3,\"ch\":6},{\"line\":3,\"ch\":12}],[{\"line\":4,\"ch\":6},{\"line\":4,\"ch\":12}],[{\"line\":7,\"ch\":9},{\"line\":7,\"ch\":15}],[{\"line\":8,\"ch\":6},{\"line\":8,\"ch\":12}],[{\"line\":5,\"ch\":0},{\"line\":5,\"ch\":1}],[{\"line\":5,\"ch\":6},{\"line\":5,\"ch\":12}],[{\"line\":6,\"ch\":6},{\"line\":6,\"ch\":12}],[{\"line\":6,\"ch\":0},{\"line\":6,\"ch\":1}],[{\"line\":5,\"ch\":6},{\"line\":5,\"ch\":12}],[{\"line\":6,\"ch\":6},{\"line\":6,\"ch\":12}],[{\"line\":7,\"ch\":0},{\"line\":7,\"ch\":1}],[{\"line\":0,\"ch\":0},{\"line\":0,\"ch\":1}],[{\"line\":7,\"ch\":5},{\"line\":7,\"ch\":6}],[{\"line\":0,\"ch\":4},{\"line\":0,\"ch\":10}],[{\"line\":3,\"ch\":6},{\"line\":3,\"ch\":12}],[{\"line\":4,\"ch\":6},{\"line\":4,\"ch\":12}],[{\"line\":7,\"ch\":9},{\"line\":7,\"ch\":15}],[{\"line\":8,\"ch\":6},{\"line\":8,\"ch\":12}],[{\"line\":0,\"ch\":16},{\"line\":0,\"ch\":28}],[{\"line\":7,\"ch\":21},{\"line\":7,\"ch\":33}],[{\"line\":0,\"ch\":4},{\"line\":0,\"ch\":10}],[{\"line\":3,\"ch\":6},{\"line\":3,\"ch\":12}],[{\"line\":4,\"ch\":6},{\"line\":4,\"ch\":12}],[{\"line\":7,\"ch\":9},{\"line\":7,\"ch\":15}],[{\"line\":8,\"ch\":6},{\"line\":8,\"ch\":12}],[{\"line\":1,\"ch\":0},{\"line\":1,\"ch\":1}],[{\"line\":8,\"ch\":0},{\"line\":8,\"ch\":1}],[{\"line\":9,\"ch\":11},{\"line\":9,\"ch\":12}],[{\"line\":10,\"ch\":39},{\"line\":10,\"ch\":40}],[{\"line\":0,\"ch\":4},{\"line\":0,\"ch\":10}],[{\"line\":3,\"ch\":6},{\"line\":3,\"ch\":12}],[{\"line\":4,\"ch\":6},{\"line\":4,\"ch\":12}],[{\"line\":7,\"ch\":9},{\"line\":7,\"ch\":15}],[{\"line\":8,\"ch\":6},{\"line\":8,\"ch\":12}],[{\"line\":2,\"ch\":0},{\"line\":2,\"ch\":1}],[{\"line\":3,\"ch\":17},{\"line\":3,\"ch\":18}],[{\"line\":4,\"ch\":17},{\"line\":4,\"ch\":18}],[{\"line\":9,\"ch\":0},{\"line\":9,\"ch\":1}],[{\"line\":3,\"ch\":0},{\"line\":3,\"ch\":1}],[{\"line\":10,\"ch\":0},{\"line\":10,\"ch\":1}],[{\"line\":3,\"ch\":18},{\"line\":3,\"ch\":19}],[{\"line\":4,\"ch\":0},{\"line\":4,\"ch\":1}],[{\"line\":11,\"ch\":0},{\"line\":11,\"ch\":1}]]"}
!@%STYLE%@!
Compare the call with distinct addresses to the function body. Then consider a call passing the same address for both parameters: the assignment through `b` changes the value read through `a`. section 12.3
Aliasing means accessing the same object through different pointers. It matters both to the program’s result and to optimization: if a call might change an object through another pointer, the compiler cannot simply assume its earlier value still holds. section 12.3
TAKEAWAY — Treat possible aliases as part of a pointer interface’s contract.
- Except for character types, only pointers of the same base type may alias. In the contrasting `size_t const*` and `double*` example, the write through the latter cannot change the object read through the former; defeating that assumption produces undefined behavior. section 12.3
- Avoid taking a local variable’s address when it is unnecessary. The `&` operator is unavailable for a `register` variable, preventing that variable from aliasing; this approach is not useful for arrays. section 12.3 section 13.2.2
- Use `restrict` only when callers can meet its access requirements. It helps specify aliasing properties of function parameters, but those requirements may not be checked at compile time. section 15.2 section 15.4
1 void* memcpy(void*restrict s1, void const*restrict s2, size_t n);
2 void* memmove(void* s1, const void* s2, size_t n);
!@%STYLE%@!
{"css":"{\"css\": \"font-weight: bold;\"}","target":"[[{\"line\":0,\"ch\":0},{\"line\":0,\"ch\":1}],[{\"line\":1,\"ch\":25},{\"line\":1,\"ch\":26}],[{\"line\":0,\"ch\":4},{\"line\":0,\"ch\":8}],[{\"line\":1,\"ch\":4},{\"line\":1,\"ch\":8}],[{\"line\":0,\"ch\":10},{\"line\":0,\"ch\":16}],[{\"line\":0,\"ch\":4},{\"line\":0,\"ch\":8}],[{\"line\":1,\"ch\":4},{\"line\":1,\"ch\":8}],[{\"line\":0,\"ch\":22},{\"line\":0,\"ch\":30}],[{\"line\":0,\"ch\":35},{\"line\":0,\"ch\":45}],[{\"line\":0,\"ch\":22},{\"line\":0,\"ch\":30}],[{\"line\":0,\"ch\":60},{\"line\":0,\"ch\":66}],[{\"line\":1,\"ch\":44},{\"line\":1,\"ch\":50}],[{\"line\":0,\"ch\":56},{\"line\":0,\"ch\":57}],[{\"line\":1,\"ch\":0},{\"line\":1,\"ch\":1}],[{\"line\":0,\"ch\":4},{\"line\":0,\"ch\":8}],[{\"line\":1,\"ch\":4},{\"line\":1,\"ch\":8}],[{\"line\":1,\"ch\":10},{\"line\":1,\"ch\":17}],[{\"line\":0,\"ch\":4},{\"line\":0,\"ch\":8}],[{\"line\":1,\"ch\":4},{\"line\":1,\"ch\":8}],[{\"line\":1,\"ch\":28},{\"line\":1,\"ch\":38}],[{\"line\":0,\"ch\":60},{\"line\":0,\"ch\":66}],[{\"line\":1,\"ch\":44},{\"line\":1,\"ch\":50}]]"}
!@%STYLE%@!
The declarations contrast `memcpy`, whose source and destination objects must not overlap, with `memmove`, which permits equal pointers or overlapping objects. section 15.2
Character pointers need particular care: their aliasing exception makes exclusivity important in string-processing interfaces. Passing the same format string as both the `printf` format and its `%s` argument is identified here as a `restrict` violation with undefined behavior, even if an execution appears to print the expected result. Establish correctness before seeking a speedup, and measure any performance claim. section 15.2 section 15.4





