[comp.std.c] varargs vs. stdargs

gnb@bby.oz (Gregory N. Bond) (11/14/89)

I'm-sure-this-has-been-hashed-to-death-before-but:

Is there some method of specifying varadic functions that is portable
to both old (varargs) and new (stdargs) implementations?  Is there an
ANSI prototype for old varargs functions?  Or do I have two prototyes
and two implementations surrounded by #if __STDC__?  (My varargs is
the SunOs 3.5 one, in case there are many versions...)

Greg.
--
Gregory Bond, Burdett Buckeridge & Young Ltd, Melbourne, Australia
Internet: gnb@melba.bby.oz.au    non-MX: gnb%melba.bby.oz@uunet.uu.net
Uucp: {uunet,pyramid,ubc-cs,ukc,mcvax,prlb2,nttlab...}!munnari!melba.bby.oz!gnb

gwyn@smoke.BRL.MIL (Doug Gwyn) (11/14/89)

In article <GNB.89Nov14103800@baby.bby.oz> gnb@bby.oz (Gregory N. Bond) writes:
>Is there some method of specifying varadic functions that is portable
>to both old (varargs) and new (stdargs) implementations?

The simple answer is that at some level you have to switch on __STDC__.

>Is there an ANSI prototype for old varargs functions?

No, such functions were not legal C although they happened to work in
most implementations.  Because of the widespread use of printf() in
applications, it behooved implementors to figure out some solution.

>Or do I have two prototyes and two implementations surrounded by
>#if __STDC__?

Some people use macros to make this a bit less painful, but in any
event in the definition of the body of a variadic function you have
to pick up the "fixed" arguments via va_arg() for varargs, but
they're already accessible under stdarg.

maart@cs.vu.nl (Maarten Litmaath) (11/15/89)

How about this?
--
/*
 * my_varargs.h
 */
#ifndef MY_VARARGS_H
#define MY_VARARGS_H

#ifdef	__STDC__

#define		EXTERN_VARARGS(type, f, args)	extern	type	f args
#define		VARARGS(type, f, args)		type	f args
#define		VA_START(ap, type, start)	va_start(ap, start)
#include	<stdarg.h>

#else	/* __STDC__ */

#define		EXTERN_VARARGS(type, f, args)	extern	type	f()
#define		VARARGS(type, f, args)		type	f(va_alist) \
						va_dcl
#define		VA_START(ap, type, start)	va_start(ap); \
						start = va_arg(ap, type)
#include	<varargs.h>

#endif	/* __STDC__ */

#endif	/* !MY_VARARGS_H */
--
In somefile.h:
--
EXTERN_VARARGS(void, error, (error_p_type error, ...));
--
In somefile.c:
--
/* VARARGS1 */
VARARGS(void, error, (error_p_type error_p, ...))
{
#ifndef __STDC__
	error_p_type	error_p;
#endif	/* !__STDC__ */

	va_list ap;

	VA_START(ap, error_p_type, error_p);
	vfprintf(stderr, error_p->message, ap);
	va_end(ap);
	exit(error_p->status);
}
-- 
[...] like a roving gang.  "Ah, here's a NEW almost-empty group to post train
schedules and core dumps in!"  (Joe Buck) | maart@cs.vu.nl, mcsun!botter!maart