gripe: variable arg lists

Brian Katzung katzung at ucsfcgl.UUCP
Thu Nov 22 08:27:27 AEST 1984


> But there is a standard method of dealing with variable argument lists.
> 	#include <varargs.h>
> The contents of the file differ from machine to machine, but the `entry points'
> are standard.
> 
> As to why _doprnt() was used: that's pretty easy.  There is no standard
> analog to printf which accepts a variable argument list *as an argument*.
> 
> 	Marty Shannon
> UUCP:	{alice,rabbit,research}!mjs
> 	(rabbit is soon to die.  Does this mean alice is pregnant?  Yup!)
> Phone:	201-582-3199

(I didn't see the original article so I'm not sure what was said.
My apologies if I'm repeating something.)

The "standard method" can't always be applied.  As far as I know, it
is impossible to do under some implementations (I'd be delighted to
have somebody prove me wrong by providing a non-trivial solution (ie,
one that doesn't consist of separate entry points)).

The problem arises on systems like ZILOG that put some arguments in
registers (it may speed up execution a little, but it slows me
down a lot).

Fixing argument references in the case of printf-like routines is messy,
but straight-forward:

printf(rformat, rarg1, rarg2, rarg3, sarg1)
/* r = in register, s = on stack */
char	*rformat...
{
	int	regcnt = 3;
	char	*argp = &rarg1;		/* (argp <- addr of copy of reg) */

	/*
	 * Current argument is *argp.  Next argument is:
	 */
	if (--regcnt)			/* Not last register argument. */
		(Advance pointer by appropriate amount)
	else				/* Switch from r to s args. */
		argp = &sarg1;
}

Now suppose I have a pair of functions, say "xlist" and "xvec", that have
been written on another system and have been "sprinkled" into numerous
modules.  The routines have the following structure:

xvec (vec)
xtype	*vec; 	/* ((xtype) 0) terminated vector. */
{ body }

xlist (element1)	/* Called xlist(e1, e2, ..., en, (xtype) 0); */
xtype	element1;
{
	xvec(&element1);	/* Let xvec do the work. */
}

On a Zilog system, xvec has to be split into a routine that takes a vector,
and a routine that takes the address of the first "register" argument and
the address of the first stack argument.  All occurrences of xlist-style
calls to xvec have to be changed to xvec2(&rarg1, &sarg1), and xvec
becomes "xvec2(vec, &vec[4])" (xvec2 now does the work).

				Brian Katzung  ucbvax!ucsfcgl!katzung



More information about the Comp.lang.c mailing list