Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!watmath!clyde!burl!ulysses!allegra!mit-eddie!genrad!panda!talcott!harvard!seismo!brl-tgr!tgr!NEVILLE%umass-cs.csnet@csnet-relay.arpa From: NEVILLE%umass-cs.csnet@csnet-relay.arpa (Neville D. Newman) Newsgroups: net.unix-wizards Subject: C compiler implements wrong semantics Message-ID: <2147@brl-tgr.ARPA> Date: Sun, 2-Feb-86 05:11:49 EST Article-I.D.: brl-tgr.2147 Posted: Sun Feb 2 05:11:49 1986 Date-Received: Mon, 3-Feb-86 06:34:50 EST Sender: news@brl-tgr.ARPA Lines: 76 This is posted to unix-wizards instead of to net.lang because i believe that it shows faulty semantics in the Unix C compiler. i don't know the proper to get to arbitrary newsgroups, being an Internet person, so if the moderator would kindly forward it there i would appreciate it. While digging through the guts of the portable C compiler, i noticed that it produced exactly the same code for two statements that i think have different semantics. According to my C references, the unary operators have precedence over binary operators (and are evaluated right to left). The rule for pre- and post-increment (and -decrement) operators is, of course, that a++ changes the value of a after the value of the term is used, so that the change is a side-effect. ++a, on the other hand changes the value of a before the term is used and is therefore entirely equivalent to (a += 1) or (a = a+1). The C compiler on our 4.2bsd system, however, seems to consider the "before" and "after" to be relative to the higher level *expression* being evaluated rather than just the individual term. In the assembly output for the simple program that follows, the increment or decrement is always placed before or after the block of statements that implement the C assignment, never in the midst of that block where it should sometimes appear. According to my books, if a is 5, then (a++ + a) ought to evaluate to 11. On 4.2bsd (or any system using the pcc, i imagine) it evaluates to 10. On VMS with VAX-C v2.1, it evaluates to 11. On CP/M-68K with the Alcyon compiler, it is 10. The Alcyon compiler strives for compatibility with version 7 Unix. So the questions for the day are: Is pcc "right" because it is sort of the defacto standard? (i have a friend who claims that BNF and such are useless, the compiler is the only definition of a language that counts) Is this discrepancy between Unix C's behaviour and description already widely known and carefully worked around? Should i attempt to fix it and possibly break some code or leave it alone for old time's sake? This code should check several facets of the pre-/post- increment/decrement problem. The pre-increments should be give results of 12 on all systems, or else there's a *bad* problem. The post-increments give 10 on Unix, 11 on VMS. i think 11 is correct, based on the language description. #include main() { int a; int b; /* check post-increments */ a = 5; b = a + a++; printf("b = a + a++ yields %d\n",b); a = 5; b = a++ + a; printf("b = a++ + a yields %d\n",b); a = 5; b = a + (a++); printf("b = a + (a++) yields %d\n",b); a = 5; b = (a++) + a; printf("b = (a++) + a yields %d\n",b); /* check pre-increments */ a = 5; b = a + ++a; printf("b = a + ++a yields %d\n",b); a = 5; b = ++a + a; printf("b = ++a + a yields %d\n",b); a = 5; b = a + (++a); printf("b = a + (++a) yields %d\n",b); a = 5; b = (++a) + a; printf("b = (++a) + a yields %d\n",b); }