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