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?