Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!sdd.hp.com!hplabs!pyramid!markhall From: markhall@pyrps5.pyramid.com (Mark Hall) Newsgroups: comp.std.c Subject: stdarg: va_list pass by value? Message-ID: <136152@pyramid.pyramid.com> Date: 30 Nov 90 09:17:29 GMT Sender: daemon@pyramid.pyramid.com Reply-To: markhall@pyrps5.pyramid.com (Mark Hall) Organization: Pyramid Technology Corp., Mountain View, CA Lines: 66 Consider the program below to print out two strings using stdarg. I want to know what should happen when you pass a va_list object as an argument to a procedure which uses it to grab arguments. Should the va_list object have pass-by-value semantics, or pass-by-reference (ie, does the "value" of the va_list object change)? #include string1(va_list ap) { printf("%s\n", va_arg(ap,char*)); } string1_or_2(int dummy,...) { va_list ap; va_start(ap,dummy); string1(ap); /* print out "string1" */ /* what will the next line print out? * string1 or string2? */ printf("%s\n", va_arg(ap,char*)); va_end(ap); } main() { string1_or_2(1,"string1", "string2"); } So what do you think? string1 string2 or string1 string1 I contend that every ANSI compiler in existence will emit the latter output. If the standard suggests that it should be the former, then the tried-and-true method of passing around the address of the stack as the va_list will not cut it. If it should be the latter, then implementing varargs with non-trivial (ie, non-VAX) calling conventions will require some ugly shenanigans. Funny, I started posted this because I thought the first output sequence was the "correct" one. However, the more I look at it, the better the second output sequence looks. If you want the first sequence, you should be able to declare string1 differently and pass it in the *address* of the va_list: string1(va_list *ap) { printf("%s\n", va_arg(*ap, char*)); } string1_or_2(int dummy,...) { va_list ap; va_start(ap,dummy); string1(&ap); /* pass in the address */ ... Hmmm. However, what about all those standard procedures (vfprintf, _doprnt, etc) which chew up va_list objects (but which accept va_list parms, NOT va_list* parms)? Can someone set the record straight here? Does the standard address this issue adequately? -Mark Hall (smart mailer): markhall@pyrps5.pyramid.com (uucp paths): {ames|decwrl|sun|seismo}!pyramid!markhall