Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/5/84; site rexago1.UUCP Path: utzoo!watmath!clyde!burl!ulysses!bellcore!decvax!cwruecmp!rexago1!rich From: rich@rexago1.UUCP (K. Richard Magill) Newsgroups: net.unix-wizards,net.unix Subject: Re: Function Parameter Expansion Message-ID: <195@rexago1.UUCP> Date: Sun, 16-Mar-86 17:24:10 EST Article-I.D.: rexago1.195 Posted: Sun Mar 16 17:24:10 1986 Date-Received: Tue, 18-Mar-86 07:20:57 EST References: <1713@brl-smoke.ARPA> Reply-To: rich@rexago1.UUCP (K. Richard Magill) Organization: Roadway Express Inc., Akron, OH Lines: 49 Xref: watmath net.unix-wizards:17243 net.unix:7401 In article <1703@brl-smoke.ARPA> tanj@ucbvax.uucp writes: >I just spent an hour trying to figure out why my working program >suddenly stopped working. Here's the culprit: > > expand(*ptr++,*ptr++,*ptr++,ptr++,ptr++,ptr++); > Effectively, all "full C" compilers *PUSH* right to left. Evaluation order may be changed by the optimizer or whoever. Y'see C does not quite define how parameters are passed to functions. In order to be able to use functions of varying numbers of parameters (like fprintf & family) it *implies* that the caller pushes and pops while the callee only reads. Actually this could be done left to right if an additional argument was added that represented the number of arguments. (or some such) On one compiler I worked with, you had three options: 1) caller pushes r to l and pops, callee just reads. (easiest to debug, allows varying numbers af arguments) 2) caller pushes (r to l) callee pops. In this case callee *must* know the number of arguments. on this compiler that was the user's problem. 3) caller pushes (r to l) *except* for the left most argument which was left in a register. callee pops. Again lint warns but its really up to you. These are listed in order of increasing speed. (& space) One C compiler I own offers PL/I style (caller pushes l to r, callee pops). I *think* lattice uses this. I should point out that you get very different errors using (1) than from using (3). If I call a function with 2 arguments when it is expecting 1, under (1) the second argument is ignored. Under (2), IN THIS IMPLEMENTATION, the second argument became the return address & the real return address is left on the stack. Weak argument: When order evaluation is not specified, (like for C function arguments), then evaluation of each expression *could* be passed on to other processors or the like. People actually worry about these things when: - The application is time or space CRITICAL. (z80 based controllers) - More than one compiler is in use. (linking to a fortran library, or between any of the myriad pc "C"'s) - Cottrel-esque previously working "C" code is ported to new machines/compilers/processors and doesn't initially work. K. Richard Magill if its questionable or machine specific, COMMENT IT WELL.