[comp.lang.c] ANSI C stdarg questions

rta@pixar.UUCP (Rick Ace) (12/21/89)

Consider the following ANSI C program:

----------------------------------------------------------------------
#include <stdarg.h>

/* print each number in the argument list of test(), stop at 0 */
void print1(va_list ap)
{
	int i;

	while (i = va_arg(ap, int)) 
		printf("%d\n", i);
}

/* print the sum of the numbers in the argument list of test(), stop at 0 */
void print2(va_list ap)
{
	int sum = 0, i;

	while (i = va_arg(ap, int)) 
		sum += i;
	printf("sum %d\n", sum);
}

/* argument "x" is not used, but must be present for stdarg.h */
void test(int x, ...)
{
	va_list ap;

	va_start(ap, x);
	print1(ap);
	print2(ap);
	va_end(x);
}

main(int argc, char **argv)
{
	test(0, 1, 5, 7, 0);
}
----------------------------------------------------------------------

This program works on two different ANSI implementations
(the NeXT and the SGI Iris).  That, of course, does not
guarantee conformance to the standard, and K&R 2E doesn't
address all the details, so here are two questions:

1)  Is it legal ANSI C for test() to pass the argument "ap" to
    print1() and print2() as it does in the above program?

2)  Is it legal ANSI C to traverse the argument list multiple times?
    For example,

        int sum;
        va_list ap;

        va_start(ap, x);              /* start first traversal */
        sum = 0;
        while (i = va_arg(ap, int)) 
                printf("%d\n", i);
        va_end(ap);
        va_start(ap, x);              /* start second traversal */
        sum = 0;
        while (i = va_arg(ap, int)) 
                sum += i;
        va_end(ap);
        printf("sum %d\n", sum);

Please answer both questions.  No partial credit will be given :-)

Rick Ace
{sun,ucbvax}!pixar!rta

chris@mimsy.umd.edu (Chris Torek) (12/21/89)

In article <8217@pixar.UUCP> rta@pixar.UUCP (Rick Ace) writes:
>1)  Is it legal ANSI C for test() to pass the argument "ap" to
>    print1() and print2() as it does in the above program [deleted]?

Yes.  Unfortunately, it is not legal afterwards to do more with `ap'
in test().

>2)  Is it legal ANSI C to traverse the argument list multiple times?
>[using va_start + series of va_arg + va_end + va_start + va_arg + va_end]

Yes, this is explicitly allowed.

As you noted, the only real problem is the obnoxious (and completely
unnecessary, since the `...' syntax must be recognised by the compiler
and therefore compilers could recognise some other hidden syntax for
va_start's expansion) requirement for an `anchor' (the `x' in your
`test').
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@cs.umd.edu	Path:	uunet!mimsy!chris