stdarg: va_list pass by value?

Mark Hall markhall at pyrps5.pyramid.com
Fri Nov 30 20:17:29 AEST 1990


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 <stdarg.h>
	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 at pyrps5.pyramid.com
	   (uucp paths): {ames|decwrl|sun|seismo}!pyramid!markhall



More information about the Comp.std.c mailing list