[comp.lang.c] Can va_arg

sandra%jensen.utah.edu@cs.utah.edu (Sandra Loosemore) (08/03/90)

The title says it all: is it legitimate, portable usage to treat
va_arg() as an lvalue?  Specifically, can I take the address of its
return value?  It looks like it will work in the C implementations I
currently have access to, but I'm not sure whether that's a bug or
a feature.

-Sandra Loosemore (sandra@cs.utah.edu)

steve@taumet.com (Stephen Clamage) (08/05/90)

sandra%jensen.utah.edu@cs.utah.edu (Sandra Loosemore) writes:

>The title says it all: is it legitimate, portable usage to treat
>va_arg() as an lvalue?  Specifically, can I take the address of its
>return value?

The ANSI C standard says (section 4.8.1.2):
"The va_arg macro expands to an expression that has the type and value
of the next argument in the call."

An expression is not an lvalue.  If you need to take the address of
the parameter (as for passing the address to another routine), you
can assigned it to a local temp and take the address of that.
That is, instead of
	foo(&va_arg(ap, T));
you write
	T temp = va_arg(ap, T);
	foo(&temp);
The latter has the same effect and is legal and portable.
-- 

Steve Clamage, TauMetric Corp, steve@taumet.com

colin@array.UUCP (Colin Plumb) (08/05/90)

In article <1990Aug3.091749.10018@hellgate.utah.edu> sandra%jensen.utah.edu@cs.utah.edu (Sandra Loosemore) writes:
>  Specifically, can I take the address of its
>return value?  It looks like it will work in the C implementations I
>currently have access to, but I'm not sure whether that's a bug or
>a feature.

Section 4.8.1.2: "The va_arg macro expands to an expression that has the
type and value of the next argument in the call."

In particular, not necessarily an lvalue, just a general expression.

Arguments need not be passed in addressible storage (registers are possible),
so taking the address is not guaranteed.

(Yes, most current compilers copy the arguments into memory so they can
refer to them from called procedures that are passed the va_list, but
a really intelligent compiler might do that only if the va_list is
passed to a called procedure, or something trickier.)
-- 
	-Colin