friedl@vsi.UUCP (Stephen J. Friedl) (04/03/88)
In article <185@premise.ZONE1.COM>, chang@premise.ZONE1.COM writes: > > [ comments about "useless" cdecl and function calling conventions in MSC ] > > The calling convention we're talking about here isn't call-by-name or > call-by-value. It's simply the order in which parameters are passed > on the stack. And in C, that order *must* be right to left in order > to support variable length functions like printf. If it were left to > right, then the printf function wouldn't know where to find its format > string. Note that while right-to-left arg passing may be used in the PC, this is defined *by* the PC and/or MSC and not by the C language (it is specifically "Unspecified Behavior"). There are indeed machines such as the WE32100 (AT&T 3B2) and I believe the PDP-11 that are happy to pass args in the other direction, and *my* 3B2 printf() still says "hello, world\n" :-) My limited cause-and-effect detectors indicate that when the stack grows up (i.e., "push" increments the stack pointer) then args go left->right, and if the stack grows down then args go right->left. Upward-growing stacks seem to be much less common; anybody know of others? Which direction do their args pass? Also, I imagine that a clever compiler writer could manage to define a calling convention that would work properly in either direction, albeit less efficiently in the "wrong" direction. Try this on your favorite compiler to see what you get. main() { static char *dirwords[] = { "left", "right" }; char **dirptr = dirwords; printf("Direction is %s to %s\n", *dirptr++, *dirptr++); } -- Steve Friedl V-Systems, Inc. "Yes, I'm jeff@unh's brother" friedl@vsi.com {uunet,ihnp4}!vsi.com!friedl attmail!vsi!friedl
platt@emory.uucp (Dan Platt) (04/04/88)
In article <476@vsi.UUCP> friedl@vsi.UUCP (Stephen J. Friedl) writes: >In article <185@premise.ZONE1.COM>, chang@premise.ZONE1.COM writes: >> >> [ comments about "useless" cdecl and function calling conventions in MSC ] >> >> The calling convention we're talking about here isn't call-by-name or >> call-by-value. It's simply the order in which parameters are passed >> on the stack. And in C, that order *must* be right... > >Note that while right-to-left arg passing may be used in the PC, >this is defined *by* the PC and/or MSC and not by the C language >(it is specifically "Unspecified Behavior")... Actually, the right/left or left/right issue isn't the point. If the convention employed by the compiler writer passes arguments and the return address of the jump on the stack, then the first argument must be the last one pushed before the call for variable length arguments, and usually, the first one or two arguements contains information about the number of arguements passed. On the IBM 370's, this is not so critical. The convention is to pass the return address in one of the registers and a pointer to the start (or end -- you choose) of an argument space (that acts like a stack - sort of) from which the routine steps forward (backwards) for the various arguements. It is the calling routine's responsibility on the 370 to provide the argument space for the call. So, in this case, it's arbitrary. In the case of the IBM PC's, it IS a stack machine. It has been the tradition for MicroSoft compilers that came before (the Fortran and Pascal compilers) to push the last argument last, so that it will be the first one on the list, nearest the return address from the subroutine call. In order for the C standard variable argument lists to work, the FIRST argument must be pushed last (nearest the return address), so that the number of elements to be poped and processed may be determined easily. For the 370, the object pointed to would have to be the first element. So the issue isn't left/right, it is which is "pushed" last, the last argument or the first. Dan Platt