That's true, but in many cases of undefined behavior, compilers take the liberty of interpreting it as an assertion. In this case, for example, it's legal for the compiler to assume that p and q don't alias when it sees this expression, because either: 1) they really don't alias, in which case the assumption and subsequent optimization is correct; or 2) they really do alias, but in that case the behavior is undefined, so the compiler's choice to apply "erroneous" optimizations is not prohibited.
It's a common approach in C compilers for inferring more optimization-relevant semantics than the language constructs explicitly specify.
It's a common approach in C compilers for inferring more optimization-relevant semantics than the language constructs explicitly specify.