[comp.lang.c] cdecl keyword in MSC

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