Args: var number & var types

Chris Torek chris at mimsy.UUCP
Fri May 13 04:14:54 AEST 1988


In article <cWW=o4y00XcRh2E04h at andrew.cmu.edu> jv0l+ at andrew.cmu.edu
(Justin Chris Vallon) writes:
[How would one implement a function foo such that ...]
>  foo(0);     /* no optional argument */
>  foo(1, c);  /* pass a character argument */
>  foo(2, i);  /* pass an integer argument */
>  foo(3, s);  /* pass a short arg */
>  foo(4, l);  /* pass a long arg */
>  foo(5, "Hello world"); /* pass a char* arg */

Doug Gwyn suggests using a union.  This is likely to work (by
which I mean more likely not to turn up implementation bugs and
perhaps less likely to confuse programmers), but is inconvenient
since C lacks aggregate constructors.  Here is a sample foo().

/* K&R C */			/* NeoC */
#include <varargs.h>		#include <stdarg.h>

void				void
foo(va_alist)			foo(int ind, ...)
	va_dcl
{				{
	va_list ap;			va_list ap;
	int ind;
	char c;				char c;
	int i;				int i;
	short s;			short s;
	long l;				long l;
	char *cp;			char *cp;

	va_start(ap);			va_start(ap, ind);
	ind = va_arg(ap, int);
					/* now copy version on left verbatim */
	switch (ind) {

	case NO_ARG:
		work0();
		break;

	/*
	 * nb: because char, short, and int are all extended to int, it
	 * is probably unnecessary to distinguish between them.
	 */
	case CHAR_ARG:
		c = va_arg(ap, int);
		work1(c);
		break;

	case INT_ARG:
		i = va_arg(ap, int);
		work2(i);
		break;

	case SHORT_ARG:
		s = va_arg(ap, int);
		work3(s);
		break;

	case LONG_ARG:
		l = va_arg(ap, long);
		work4(s);
		break;

	case STR_ARG:
		cp = va_arg(ap, char *);
		work5(cp);
		break;
	}

	va_end(ap);
}


/* note that neo-C makes an annoying semantic change to va_start */
/* (NEVER change the semantics without changing the name! grr..) */
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris at mimsy.umd.edu	Path:	uunet!mimsy!chris



More information about the Comp.lang.c mailing list