rolfe@dsuvax.uucp (Timothy J. Rolfe) (06/26/91)
Beautify, beautiful side effect!! As it stands, "q = q++;" SHOULD leave q unchanged: evaluating the right hand side we get a value (q BEFORE the increment). That is the value that is supposed to go to the left hand side. The question is WHEN the post-increment is done. On a MicroVAX-II under Ultrix we get it BOTH ways, depending on whether we use the cc, gcc, or vcc compiler --- plain cc, GNU's cc, and VAX native C. We can even go better: main() { int q=5, inc=10; void kludge(); kludge (q, inc); } void kludge(q, inc) int q, inc; { q = q++ + inc; printf ("%d\n", q); } The extra level is to get around the #@$%#@ vcc compiler's optimizing q = q++ + inc; into a simple q = 15; (since it knows the values!). cc- and gcc-compiled versions generate an answer of 16; vcc-compiled version generates an answer of 15. gcc-generated machine code for kludge: .globl _kludge _kludge: .word 0x0 addl2 8(ap),4(ap) ; <== calculated straight into q incl 4(ap) ; <== then do the post-increment pushl 4(ap) ; Assorted stuff for printf pushab LC0 calls $2,_printf ret vcc-generated machine code for kludge: kludge: .entry kludge,^m<> movl 4(ap),r2 ; <== get the q value incl 4(ap) ; <== then do the post-increment addl3 8(ap),r2,4(ap) ; <== finally calculated into q pushl 4(ap) ; Assorted stuff for printf pushal $CHAR_STRING_CONSTANTS calls #2,printf ret --- Tim Rolfe <a.k.a. ROLFE@SDNET.BITNET>
sasrer@unx.sas.com (Rodney Radford) (06/27/91)
In article <1991Jun26.154734.14439@dsuvax.uucp> rolfe@dsuvax.uucp (Timothy J. Rolfe) writes: >Beautify, beautiful side effect!! > >As it stands, "q = q++;" SHOULD leave q unchanged: evaluating the >right hand side we get a value (q BEFORE the increment). That is >the value that is supposed to go to the left hand side. The question >is WHEN the post-increment is done. ANSII C says the behaviour of the above line is indetermined (ie: implementation dependent), and should be avoided in writing portable C programs (to more that one machine, or more that one compiler, or possibly to different versions of the same compiler...). The reason ANSII could not set a standard on this is that through the years so many different versions of C existed and handled this differently. Also should be avoided statements such as: array[i++] = i; --- or --- function(++k,k,k++) These are just other examples of indeterminate side-effect expressions.... -- Rodney Radford || Computer Graphics/Imaging sasrer@unx.sas.com || SAS Institute, Inc. (919) 677-8000 x7703 || Cary, NC 27513
kurt@tc.fluke.COM (Kurt Guntheroth) (06/27/91)
> "q = q++;" SHOULD leave q unchanged: evaluating the > right hand side we get a value (q BEFORE the increment). That is > the value that is supposed to go to the left hand side. The question > is WHEN the post-increment is done. K&R says nothing about when the increment's side effect is processed, and ANSI says specifically that it is undefined. The side effect may be applied AFTER the assignment. You are probably used to the informal PDP11 semantics where q++ generates an increment instruction, but no all architectures or compilers choose this method. A better example is *p++ = *p++; which has three side effects that may be processed in arbitrary order.
madd@world.std.com (jim frost) (06/30/91)
kurt@tc.fluke.COM (Kurt Guntheroth) writes: >> "q = q++;" SHOULD leave q unchanged >K&R says nothing about when the increment's side effect is processed, and >ANSI says specifically that it is undefined. Both K&R 1 and 2 say that the behavior is undefined (p 50 and 53-54 respectively, I know 'em by heart) as does ANSI. With respect to the gcc versus vcc code difference: note that gcc produced more efficient code by evaluating in a different order. This is precisely the reason K&R give for leaving the order undefined. Happy hacking, jim