expr. evaluation order (was short circuit evaluation)
jas at rtech.UUCP
jas at rtech.UUCP
Mon Feb 23 16:49:19 AEST 1987
> 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!/
More information about the Comp.lang.c
mailing list