Richard said:
[...]
The language specifies left-to-right associativity (or its
equivalent in the form of a grammar). The compiler is free to
play games *if* it can produce the same result whenever the
original does not invoke undefined behavior. Thus, for example:
`1 + x + 2 + y' may actually be evaluated as `x + y + 3' or even
as `++TEMPRESULT' if the value of `x + y + 2' is already known.
This is a bit misleading to me. Suppose, for example, we have a
sum of signed integers, a+b+c, a and c positive, b negative,
where a+c overflows but (a-b)+c does not.
I guess you mean (a+b)+c, or (a-|b|)+c.
Then a+c invokes
undefined behaviour; however the compiler cannot know that.
It can certainly know that an addition carries the risk of
overflow. Furthermore, the compiler for a particular machine
probably has a pretty good idea of the consequences of overflow
on that machine. But in any event, evaluating a+b+c does not
require evaluating a+c.
Ergo
the compiler can alter the order to a form where there is
undefined behaviour when the original left to right order did
not.
I'm unable to follow your reasoning. You seem to be saying
that some rearrangements of valid expressions render them
invalid (I agree), that the compiler cannot be aware of this (I
disagree, but that seems to be a side-issue), and that "ergo"
the compiler is free to make trash of correct programs (and
that's where I lose your thread, and disagree with the conclusion).
Let's take the (in)famous DeathStation 9000, whose builders
connected the overflow latch to the detonator of a small fission
bomb (they felt overflow was a serious error that should not stay
hidden). If the program evaluates `1 + -42 + INT_MAX' the system
is required to produce the value `INT_MAX - 41' and is not allowed
to blow the program to Kingdom Come. Implication: on the DS9000,
the compiler's freedom to exploit the (so-called) commutativity
of addition is limited to those cases where it can be sure the
rearrangement will not change the outcome.
The HAL StinkWad represents an opposite pole in system design.
It was built by a Big Company with Big Ideas, where the idea that
"overflow is just an opportunity for More Growth" was encouraged.
The designers therefore didn't feel it was worth bothering the
programmer when an overflow or underflow occurred, and in fact
decided to cut costs by eliminating the overflow latch entirely.
On this system overflow goes undetected and causes no harm, and
the compiler is free to evaluate `1 + INT_MAX + -42' if it so
desires: The two wrap-arounds cancel each other out, and the
result of `INT_MAX - 41' pops out as required, with minimal fuss
and, er, fallout.
There are similar but worse problems with floating point numbers
- the number of significant figure depends on the actual order.
This is (probably) part of the reason for the looseness of
the Standard's description of floating-point arithmetic. See also
#pragma STDC FP_CONTRACT (in C99).