Do you use stdarg, varargs or ya-args?
Chris Torek
torek at elf.ee.lbl.gov
Fri May 10 22:00:18 AEST 1991
In article <2755 at muffin.cme.nist.gov> libes at cme.nist.gov (Don Libes) writes:
>The obvious question is: why bother using stdarg?
There is one minor efficiency reason, and, of course, the `standardness'
argument.
The efficiency reason comes about because varargs() officially works
like this:
#include <varargs.h>
/* foo takes three fixed arguments and the rest are variable */
/* VARARGS3 */
void
foo(va_alist) /* example 1 */
va_dcl
{
va_list ap;
XYZ *xp;
int i;
long l;
va_start(ap);
xp = va_arg(ap, XYZ *);
i = va_arg(ap, int);
l = va_arg(ap, long);
/* code to deal with varargs goes here */
va_end(ap);
}
People (including myself) often write something like:
/* VARARGS3 */
void
foo(xp, i, l, va_alist) /* example 2 */
XYZ *xp;
int i;
long l;
va_dcl
{
va_list ap;
va_start(ap);
/* code to deal with varargs goes here */
va_end(ap);
}
but this is not in fact correct. (I know of no systems on which it
breaks, but that does not mean such do not exist.)
Where I believe ANSI went wrong is in adding a second parameter to
va_start. The `...' syntax is not as great a problem. If one takes
the attitude (as I have done) that `if example 1 fails, get an ANSI
C compiler or forget it', we can then write foo() as:
#if __STDC__
void foo(XYZ *xp, int i, long l, ...) {
#else
void foo(xp, i, l, va_alist) XYZ *xp; int i; long l; va_dcl {
#endif
va_list ap;
va_start(ap);
/* code to deal with varargs goes here */
va_end(ap);
}
which cuts the work in half when compared with the (currently required
under the exact same assumptions):
/* example 3 */
#if __STDC__
void foo(XYZ *xp, int i, long l, ...) {
#else
/* VARARGS */
void foo(xp, i, l, va_alist) XYZ *xp; int i; long l; va_dcl {
#endif
va_list ap;
#if __STDC__
va_start(ap, l);
#else
va_start(ap);
#endif
/* code to deal with varargs goes here */
va_end(ap);
}
In any case, the requirement that the name of the last fixed argument
be repeated is a maintenance headache. The compiler already must
understand the new `...' syntax; it is little, if any, more difficult
to add at the same time one more special compiler-specific syntax or
semantic (which is then hidden behind va_start in <stdarg.h>) for
computing the address of the first varying argument. Thus even though
the `extra' argument to va_start can be hidden behind Yet Another
Macro:
#if __STDC__
#define VASTART(ap, last) va_start(ap, last)
#else
#define VASTART(ap, last) va_start(ap)
#endif
so that example 3 becomes:
/* example 4 */
#if __STDC__
void foo(XYZ *xp, int i, long l, ...) {
#else
/* VARARGS */
void foo(xp, i, l, va_alist) XYZ *xp; int i; long l; va_dcl {
#endif
va_list ap;
VASTART(ap, l);
/* code to deal with varargs goes here */
va_end(ap);
}
, I still believe that this extra argument was a mistake.
>... don't you think [old varargs style] support will always be provided
>by the vendor somehow? (All the STDC compilers already provide a
>shitload of extensions.)
Always: no; for the next 20 years: yes. :-) (Incidentally, I have
forgotten: is a shitload more or less than an oodle? I think the list
goes: one, a couple, a few, some, a dozen, a baker's dozen, lots,
oodles, a shitload, a metric shitload, ... [where is George Weinert
when you need him? :-) ])
--
In-Real-Life: Chris Torek, Lawrence Berkeley Lab CSE/EE (+1 415 486 5427)
Berkeley, CA Domain: torek at ee.lbl.gov
More information about the Comp.lang.c
mailing list