`va_dcl' macro question

Mark H. Colburn mark at jhereg.Jhereg.MN.ORG
Fri Feb 3 10:30:02 AEST 1989


In article <991 at ubu.warwick.UUCP> geoff at emerald.UUCP (Geoff Rimmer) writes:
>
>All I know about variable arguments in ANSI C is how to do prototypes,
>and define the functions.  However, I don't know how to read each of
>the arguments passed to the function.  Could someone email/post a
>simple function that will take a variable number of strings, and then
>print them to stdout one at a time.
>
>i.e.
>
>	void print_strings (char *str, ...)
>	{
>	...
>	}


In ANSI (as well as most other existing varargs), there is no way to tell 
that you are at the end of the passed parameter list.  Therefore, most
varargs-type functions have some way of determining the number and type
of arguments that they were passed.  Routines like printf and scanf assume 
that there is one argument for each '%' which also specifies they parameter
type, other routines may use a parameter count or some other means of
relaying the number and types of arguments to the routine.

Therefore, your initial routine is impossible to code portably unless
the 'str' parameter has some indication as to the number of parameters
which were passed to the print_strings function.

If we add a parameter count to the print strings function, it will work,
and can be coded as such:


	#include <stdio.h>
	#include <sdtarg.h>

	void
	print_strings(int num, ...)
	{
	    va_list	va;

	    va_start(va, num);
	    while (num--) {
		puts(va_arg(va, char *));
	    }
	    va_end(va);
	}

It could then be called as such:

	print_strings(2, "hi", "there");
	print_strings(4, "this", "is", "a", "test");

Note, that the following call,

	print_strings(3, "this", "is", "a", "test");

would be completely legal, but would only print:

	this
	is
	a


If you wanted an error function, which allowed for printf() style error
messages, it could be coded like this:


	#include <stdio.h>
	#include <stdarg.h>

	void
	error(char *format, ...)
	{
	    va_list	va;

	    va_start(va, format);
	    vfprintf(stderr, format, va);
	    va_end(va);
	}


It's pretty easy once you see how to do it...


-- 
Mark H. Colburn                  "Look into a child's eye;
Minnetech Consulting, Inc.        there's no hate and there's no lie;
mark at jhereg.mn.org                there's no black and there's no white."



More information about the Comp.lang.c mailing list