Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!husc6!mit-eddie!ll-xn!ames!sgi!archer From: archer@elysium.SGI.COM (Archer Sully) Newsgroups: comp.lang.c Subject: Re: another auto-increment problem Message-ID: <6484@sgi.SGI.COM> Date: Fri, 25-Sep-87 20:21:05 EDT Article-I.D.: sgi.6484 Posted: Fri Sep 25 20:21:05 1987 Date-Received: Sun, 27-Sep-87 05:49:18 EDT References: <3680001@wdl1.UUCP> Sender: daemon@sgi.SGI.COM Organization: Silicon Graphics Inc, Mountain View, CA Lines: 81 Summary: this really is common practice... In article <3680001@wdl1.UUCP>, rion@wdl1.UUCP (Rion Cassidy) writes: > > Consider the following definitions: > > float junk[3], *junk_ptr; > /* junk contains x,y,z coords */ > > and use thereof: > > junk_ptr = (float *) junk; > xfpt(*junk_ptr++, *junk_ptr++, *junk_ptr); > /* transform x,y,z coords to a coord new system */ > > At first glance, most people would assume that the following function > call is equivalent, but slightly slower: > > xfpt(junk[0], junk[1], junk[2]); > > This assumption is based on the premise that the arguments to xfpt() > are evaluated left to right; if their are *NOT* we can be sure that we > will get the wrong values passed to xfpt. > ...(stuff deleted about order of evaluation) > Are their any C-compiler implementors out there that would care to > comment? > > Rion Cassidy > > {ucbvax|sgi|sun}!wdl1!rion I'm not a C-compiler implementor, but I think I'll comment anyway. The use of increment and decrement operators in function calls is always considered non-portable, precisely because order of evaluation isn't defined in C (cf K&R pp 212). the following program is roughly equivalent to your fragment: main() { float j[3], *jp; void foo(); jp = (float *) j; foo(*jp++, *jp++, *jp); return(0); } void foo(x,y,z) float x,y,z; { } and here's what lint had to say about it: t.c: t.c(7): warning: jp evaluation order undefined ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ t.c(7): warning: jp evaluation order undefined ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ t.c(13): warning: argument x unused in function foo t.c(13): warning: argument y unused in function foo t.c(13): warning: argument z unused in function foo foo, arg. 1 used inconsistently t.c(14) :: t.c(7) foo, arg. 2 used inconsistently t.c(14) :: t.c(7) foo, arg. 3 used inconsistently t.c(14) :: t.c(7) As for reasons why arguments to functions are evaluated right to left, here's a pretty good one. It may be more efficient to evaluate each argument just before it is pushed, rather than evaluating the argument list and then pushing. Remember that most C-compilers push arguments right to left rather than left to right, for various and sundry reasons. If you find one that pushes arguments right to left, it probably evaluates that way, too. Archer Sully archer@sgi.com {ucbvax,sun,pyramid,ames}!sgi!archer