[comp.lang.c] Variable Numbers of Args to Functions in ANSI C.

sklein@bonnie.ics.uci.edu (Steve Klein) (04/30/89)

If I forward-declare the function:

	int func(a, b, ...);

Then how do I define and call 'func'?

I tried:
    	#include <varargs.h>

    	int func(a, b, va_alist);
    	int a, b;
    	va_dcl
    	{
    	    ...
    	}

but GNU CC says 'number of args doesn't match prototype'.

Trying
    	int func(a, b, c, d);
    	int a, b, c, d;
    	{
    	    ..casting c & d where appropriate..
    	}

this, of course, moans when I call func without all 4 params:

    	func (actual_a, actual_b);

I _thought_ in ANSI C that the trailing '...' told the compiler not to
check the number or types of the parameters that followed. Is there a way
to do this, or does one need C++ with its overloading for this kind of stuff?
I could use the -traditional switch on gcc, but I'd like _some_ kind of
type checking! Is this a compiler bug or something I don't understand
about ANSI?

composer@bu-cs.BU.EDU (Jeff Kellem) (05/01/89)

In article <13024@paris.ics.uci.edu> sklein@bonnie.ics.uci.edu (Steve Klein) writes:
>If I forward-declare the function:
>
>	int func(a, b, ...);
>
>Then how do I define and call 'func'?
>
>I tried:
>    	#include <varargs.h>
>
>    	int func(a, b, va_alist);
>    	int a, b;
>    	va_dcl
>    	{
>    	    ...
>    	}
>
>but GNU CC says 'number of args doesn't match prototype'.

GCC is correct with this.  For one, <varargs.h> is not (as far as I know)
part of the ANSI standard.  What you want to use is <stdarg.h>.

So, basically what you want in ANSI C for the above is something like the
following: 

	#include <stdarg.h>

	int func(int, int, ...);

	...

	int func(int a, int b, ...)
	{
	   va_list arg_pointer;
	   int foo;
	 ...
	/* Then in here, call va_start(arg_pointer, b); */
	/*   to initialize the argument pointer to the optional */
	/*   parameter list. */

	   va_start(arg_pointer, b);

	/* Successive calls to va_arg will get the remaining args. */

	   foo = va_arg(arg_pointer, int);

	/* Then, finally call va_end to reset everything back to normal. */

	   va_end(arg_pointer);
	 ...
	}
	
Hope this helps ... Enjoy ...


                               -jeff

Jeff Kellem
INTERNET: composer@bu-cs.bu.edu  (or composer%bu-cs.bu.edu@bu-it.bu.edu)
UUCP: ...!harvard!bu-cs!composer