varargs...help appreciated

Chris Torek chris at mimsy.umd.edu
Sun Nov 4 19:17:30 AEST 1990


In article <1990Nov2.170614 at madmax.Viewlogic.COM>
kenc at madmax.Viewlogic.COM (Kenstir) writes:
>I passed [a variable] argument list to a function, took a couple of
>parameters off, then tried to pass the rest of the argument list down
>to another function. ...

This can be done, but not the way you think.  getMsg is correct:

[Apologies for the long quotes; I have squished them vertically.  I
 do not recommend coding in this style.]
>char *getMsg(va_alist) va_dcl { va_list args; int msg_id;
>    va_start(args); msg_id = va_arg(args, int);
>    vsprintf(message, msg_array[msg_id], args);
>    va_end(args);
>    return (message);
>}

Note well the fact that getMsg (which is correct and works) must
(and does) call vsprintf, not sprintf.  That `v' is important.

The next function, however, is wrong:

>void err(va_alist) va_dcl { va_list args; char *cp, *ret, *app; int num;
>    va_start(args); app = va_arg(args, char *);
>    num = va_arg(args, int);
>    ret = getMsg(num, args);

Here is the erroneous line.  How do you expect getMsg to work when you
had to call vsprintf?  If getMsg was good enough to do the trick, why
would vsprintf exist at all?

The fix, then, is to write a `vgetMsg' function.  In the process it
is simplest to rewrite getMsg in terms of vgetMsg:

	vgetMsg(msg_id, ap) int msg_id; va_list ap; {
		(void) vsprintf(message, msg_array[msg_id], args);
		return (message);
	}
	getMsg(va_alist) va_dcl {
		va_list args; int msg_id; char *ret;
		va_start(args); msg_id = va_arg(args, int);
		ret = vgetMsg(msg_id, args); va_end(args);
		return (ret);
	}

Now change the last quoted line of `err' to

	ret = vgetMsg(num, args);


>p.s.  Anyone got any varargs macros, portable between
>      traditional varargs and ANSI stdarg?

If you mean what I think you mean, it cannot be done.  The reason
is that `va_start' has the same name in <varargs.h> and <stdarg.h>
but the former version (used above) has only one parameter while the
latter has two.  It is thus impossible to write a single implementation.

If you mean the other thing I think you mean, it can be done, but it
looks horrible (and I will not even give an example).
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 405 2750)
Domain:	chris at cs.umd.edu	Path:	uunet!mimsy!chris



More information about the Comp.lang.c mailing list