stdarg: va_list pass by value?

Mark Hall markhall at pyrps5.pyramid.com
Sat Dec 1 06:21:49 AEST 1990


In article <136152 at pyramid.pyramid.com>, and in blissful ignorance, I wrote:

>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");
>	}

I should have waited until I read the standard before shooting this off
(didn't have it at home last night).  It covers this very clearly:

	The object AP may be passed as an argument to another function;
	if that function invokes the VA_ARG macro with parameter AP,
	the value of AP in the calling function is indeterminate and
	shall be passed to the va_end macro prior to any further
	reference to AP.

The program above is non-conforming.  The output can go either way.

So. . . let me state the problem in another way.  Instead of passing AP
to a procedure, what if I just assign it to another AP?

	#include <stdarg.h>
	foo(int dummy, ...)
	{
		va_list ap1, ap2;
		char *cp1,*cp2;
		va_start(ap1,dummy);
		ap2 = ap1; 			/* will ap2 "track" ap1? */
		cp1 = va_arg(ap1,char *);
		cp2 = va_arg(ap2,char *);
		printf("%s %s\n", cp1, cp2);
	}
	main()
	{
		foo(1,"string1","string2");
	}

Here, will it print "sting1 string2" or "string1 string1"?  The
standard does not say what happens when you *assign* a va_list object
(as opposed to passing it as an argument).  Obviously, the standard
included the clause about passing the AP object because some architectures
cannot have va_list be a pointer to the call stack.  Some architectures
require a pointer to a structure or something which can hold some runtime
information.  Since the standard explicitly calls out the indeterminacy
of passing AP objects as arguments, shouldn't it also call out the 
indeterminacy of assigning AP objects?

-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