Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!sdd.hp.com!caen!hellgate.utah.edu!dog.ee.lbl.gov!elf.ee.lbl.gov!torek From: torek@elf.ee.lbl.gov (Chris Torek) Newsgroups: comp.std.c Subject: Re: vs. function prototypes Keywords: usage Message-ID: <14532@dog.ee.lbl.gov> Date: 20 Jun 91 20:54:02 GMT References: <159364@pyramid.pyramid.com> <1991Jun18.145823.2512@cbnewsk.att.com> <14423@dog.ee.lbl.gov> <16456@smoke.brl.mil> Reply-To: torek@elf.ee.lbl.gov (Chris Torek) Organization: Lawrence Berkeley Laboratory, Berkeley Lines: 89 X-Local-Date: Thu, 20 Jun 91 13:54:02 PDT >In article <14423@dog.ee.lbl.gov> I wrote: >>In other words, we are not willing to bend over backwards (for compatibility) >>until it hurts, only until it is mildly uncomfortable. :-) In article <16456@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes: >But surely it's not appreciably harder, for the few uses of varargs >functions, to type the always correct [and vertically compressed and reformatted a bit by me] > void foo(va_alist) va_dcl { > char *format; ... > format = va_arg(ap, char *); > ... > } >instead of the sometimes incorrect > void foo(format, va_alist) char *format; va_dcl { > ... > } No. However, combine this with the ANSI C version: int #ifdef __STDC__ abc(int level, int type, struct foo *obj, const char *fmt, ...) #else abc(va_alist) va_dcl #endif { #ifndef __STDC__ int level; int type; struct foo *obj; char *fmt; #endif int ret; va_list ap; #ifdef __STDC__ va_start(ap, fmt); #else va_start(ap); level = va_arg(ap, int); type = va_arg(ap, int); obj = va_arg(ap, struct foo *); fmt = va_arg(ap, char *); #endif ret = vabc(level, type, obj, fmt, ap); va_end(ap); return (ret); } Now compare this with the easier (but incorrect unless __STDC__) code: int #ifdef __STDC__ abc(int level, int type, struct foo *obj, const char *fmt, ...) #else abc(level, type, obj, fmt, va_alist) int level; int type; struct foo *obj; char *fmt; va_dcl #endif { int ret; va_list ap; #ifdef __STDC__ va_start(ap, fmt); #else va_start(ap); #endif ret = vabc(level, type, obj, fmt, ap); va_end(ap); return (ret); } This saves six lines (24 vs 30; 20% less) and moves the argument matching maintenance together where it is clearer. (Suppose, for instance, the `type' argument is split into two arguments, or is merged into the `foo' object.) Now multiply this by a dozen varargs functions spread over a few hundred files. We (Keith Bostic and I, at least) would rather deal with the second (technically broken) version, due to easier maintenance, and tell those who have trouble with it to find an ANSI C compiler (and/or port GCC). -- In-Real-Life: Chris Torek, Lawrence Berkeley Lab CSE/EE (+1 415 486 5427) Berkeley, CA Domain: torek@ee.lbl.gov