Subject: Re: strict typechecking on kernel compiles [long]
To: Niklas Hallqvist <niklas@appli.se>
From: Jonathan Stone <jonathan@dsg.stanford.edu>
List: current-users
Date: 07/23/1995 19:50:46
>Does this mean *not* using prototypes at all would be more efficient?
>I thought it to mean an implied ellipsis were there. Isn't it so?
No, it doesn't. It means that there's no prototype present. This has
more-or-less the same effect as an old-style K&R function declaration,
without a prototype.
ANSI C doesn't support a prototype containing *only* an ellipsis; but
i could be mistaken. But the old-style K&R declaration with noi
arguments, and the C++ declaration with an ellipsis, mean pretty much
the same thing. (In C++, ``void foo()'' means exactly the same thing
as ``void foo(void)''.)
Try it with gcc: a program consisting of only ``void foo (...);''
gives error messages:
frob.c:1: ANSI C requires a named argument before `...'
frob.c:1: warning: function declaration isn't a prototype
In C, a prototype with a sole ellipsis argument doesn't make a lot of
sense. The ellipsis is used to indicate a variadic function
implemented using stdargs, and that __cannot__ be done without a first
named argument, to bootstrap va_start(). [That's one of the
visible differences between varargs and stdargs.]
In C++, a prototype of (...) simply means to abandon argument
typechecking on the function so declared; which is also usually
declared extern "C" anyway. (I believe the first edition of
Stroustrup said it *had* to be.)
Strictly conforming ANSI C code that calls variadic functions -- say,
``printf'' -- is required by the standard to have a prototype with an
ellipsis in scope at the point of all calls to variadic functions.
This is sufficent for an implementation (read: the compiler) to safely
use a different argument-passing convention for such functions. The
compiler must not use that calling conventions for functions declared
_without_ an ellipsis. If it did, the callers of such functions would
put their actuals somewhere other than where the callee expects to
find them.
I don't *think* the same requirement for a prototype holds true for
non-variadic functions; which makes it much harder to succesfully
compile them using a non-standard calling sequence. Simplistically,
*all* non-variadic functions need to use the *same* calling sequence.
Most architectures with C compilers predate ANSI C and thus support
varargs, which got by without prototypes. Internally, GCC tries very,
very hard to have functions declared without prototypes but
implemented with stdargs to work. This *does* have a run-time cost,
though.
Besides, who really wants to redo all the definitions of the network
code protocol-switch functions to use stdargs, *or* varargs, for those
compilers that still don't have stdargs?