Caveats
12-3
12
The compiler might conclude that the value of *pr is unaffected by the
assignment to
*pi, because double objects cannot legally be referenced by
int lvalues.
It might then use this conclusion to rewrite the above code as follows:
register double t = *pr;
*pq = t;
*pi = *pj;
*ps = t;
This is fine as long as *pi really doesn’t overlap *pr, but if your program
does something like:
double d;
pi = (int *) &d;
pr = &d;
before it executes the second fragment, the wrong value would get stored
in
*ps.
Alignment Assumptions
The compiler sometimes uses pointer type information when deciding
whether or not memory references are properly aligned for some
optimizations.
Thus, the compiler assumes that all pointer expressions are aligned as their
pointed-to types would indicate. For example,
((double *) e) is treated
as an assertion that the low 3 bits of
e are 0.
The compiler also infers more stringent alignment for individual variables
than would be indicated by their types alone, since it assumes that the
allocation is aligned according to the compiler's rules.
So, if your program defines global variables in assembly code that are
referenced by C routines, or if it has its own memory manager (e.g.,
malloc), the allocations must be aligned according to the compiler's rules
or unaligned references may result.