[comp.lang.c] expr. evaluation order

jas@rtech.UUCP (02/23/87)

> Why does C refuse to abide by the associativity/precedence rules for
> expression-evaluation that even BASIC guarantees? I can well
> understand "optimization" as an excuse but can easily imagine cases
> where normally-evaluated expressions can crash a system when
> "optimized" for eavaluation without the programmer's express consent.
> Isn't it a little arbitrary for C to mnaipulate the parts of an
> expression to its satisfaction (or whim)? In particular, this renders
> the formal verification of C-code impractical.

The above comment blurs the distinction between operator precedence and
order of evaluation.  Operator precedence rules in C (and most other
programming languages) say that a + b * c MUST be semantically
identical to a + (b * c), not (a + b) * c.  Any C compiler that
did not guarantee this would be very badly broken, indeed.  C's
operator precedence rules are almost always what one would intuitively
expect (the precedence of the bitwise &, ^, and | operators comes to
mind as an exception).

Order of evaluation is what is unspecified in C, and means just what it
says:  the order in which the compiler evaluates the components of an
expression.  For example, in the above expression, the compiler is free
to evaluate b first, squirrel away the value in a register, then
evaluate a, squirrel away that value, then evaluate c and multiply it
by the saved value of b, finally adding the saved value of a.  If a, b,
and c are simple variables (for example), any order of evaluation will
produce the same result.

Trouble arises when a, b, and c are expressions that have side effects.
For example, replace a, b, and c by functions that each print a
different message on stdout, and return a distinct constant.  The
expression will always evaluate to the same value, but the order in
which the messages appear on your terminal will be undefined.  Another
example:  replace b by a function that modifies the value of a (which,
let's say, is a global variable), and the value of the whole expression
becomes unpredictable:  if b is evaluated before a, then a's new value
gets used; otherwise, a's old value gets used.

Expressions that may be sensitive to order of evaluation are easy to
detect automatically; lint flags many of them.  Arguably, such
expressions are stylistically a little dubious, anyway.  I certainly
don't see how this particular feature "renders the formal verification
of C code impractical."  The semantics of order-sensitive expression
evaluation are quite precisely defined; they just aren't very useful,
and hence are almost certainly a sign of a bug in the program.
-- 
Jim Shankland
 ..!ihnp4!cpsc6a!\
                  rtech!jas
..!ucbvax!mtxinu!/