Func Protos with K&R Func Defs

Steve Summit scs at adam.mit.edu
Sun Mar 3 04:19:53 AEST 1991


In article <MLT9QB7 at xds13.ferranti.com> peter at ficc.ferranti.com (Peter da Silva) writes:
>In article <15354 at smoke.brl.mil> gwyn at smoke.brl.mil (Doug Gwyn) writes:
>> The [function] types must be compatible, but subject to that
>> constraint the use of "old-style definitions" is compatible with the
>> use of prototypes.
>
>Only if the prototype is in scope when it sees the definition. The compiler
>might generate a different calling sequence for prototyped functions because
>it knows the argument count.

Doug's statement is true, without exception, and reflects clear
language in X3.159 (which I have quoted from in two previous
articles on this subject), which defines exactly what is required
for two function types to be compatible.

If a function takes a fixed number of arguments, none of which is
a "narrow" type (char, short, or float), it may be defined using
old or new style syntax, defined with or without a prototype in
scope, and called with or without a prototype in scope, and under
any of these conditions the compiler is obliged to generate
consistent, compatible calling sequences.

It is only useful and legal for a compiler to use a "different"
calling sequence for functions which take variable numbers of
arguments, and such functions are specifically required to be
defined using new-style, prototype syntax, and to be called with
a valid prototype in scope.

If you understand this, you can stop reading now.  The rest of
this article is mostly taken from a comp.std.c article of mine
last month.

Peter stated that:
> The compiler
> might generate a different calling sequence for prototyped functions because
> it knows the argument count.

This is a very misleading statement.  The correct statement is

	The compiler might generate a different calling sequence
	for a function prototyped with an ellipsis, because it
	does NOT know the argument count.

As I explained in <1991Feb12.005726.22447 at athena.mit.edu>,
old-style functions may be assumed to be fixed-argument.  (This
is actually consistent with the original definition of C; printf
has always been an anomaly.)  A compiler may (and in fact,
should) use its efficient calling sequences when prototypes are
not in scope.  The variable upon which to base the choice of
function-call linkage is not the presence or absence of
prototypes, but the presence or absence of variable-length
argument lists.  (I suspect that it is a misunderstanding of this
point that is causing the confusion.)

None of this is accidental; the requirement that functions with
variable numbers of arguments be called with a prototype in scope
was made precisely so that a compiler could use one function
calling mechanism for them, and another one for all others.

If a compiler somewhere is using a different, presumably older,
presumably less efficient calling sequence for non-prototyped
functions, it is doing its customers a double disservice.  First
of all, it is confusing them badly, and probably incorrectly
rejecting compliant code.  Secondly, there is no reason to use
the less efficient calling sequence for old functions; the
"newer," presumably more efficient (though not admitting of
variable numbers of arguments) calling sequence can and should be
used.  Efficiency is, after all, the most important
consideration, and the main reason prototypes were adopted.
(Don't buy this line that they're for checking function call
consistency across source files, "for your convenience."  If
they're for your convenience, then why do you have to work to
supply them?)

                                            Steve Summit
                                            scs at adam.mit.edu



More information about the Comp.lang.c mailing list