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!/