Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!utgpu!water!watnot!watmath!clyde!rutgers!ames!amdahl!rtech!jas From: jas@rtech.UUCP Newsgroups: comp.lang.c Subject: Re: expr. evaluation order (was short circuit evaluation) Message-ID: <676@rtech.UUCP> Date: Mon, 23-Feb-87 01:49:19 EST Article-I.D.: rtech.676 Posted: Mon Feb 23 01:49:19 1987 Date-Received: Tue, 24-Feb-87 01:08:35 EST References: <844@wanginst.EDU> <4700004@uiucdcsm> Organization: Relational Technology, Alameda CA Lines: 49 > 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!/