Path: utzoo!utgpu!news-server.csri.toronto.edu!rutgers!gatech!udel!haven!mimsy!chris From: chris@mimsy.umd.edu (Chris Torek) Newsgroups: comp.lang.c Subject: Re: varargs...help appreciated Keywords: varargs Message-ID: <27416@mimsy.umd.edu> Date: 4 Nov 90 08:17:30 GMT References: <1990Nov2.170614@madmax.Viewlogic.COM> Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 63 In article <1990Nov2.170614@madmax.Viewlogic.COM> kenc@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 and 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@cs.umd.edu Path: uunet!mimsy!chris