From: meissner@osf.org (Michael Meissner)
Subject: Re: mixing prototyping and non-prototyping
Organization: Open Software Foundation
Date: 14 Aug 92 14:36:49

In article <spuler.713749345@coral.cs.jcu.edu.au> spuler@coral.cs.jcu.edu.au (David Spuler) writes:

| 
| What are the rules regarding mixing old-style and new-style functions in C
| programs?  Specifically, what mixtures must a compiler support,and which can
| be legally allowed to bomb?
| 
| Can a prototyped function be legally called without a prototype in scope?  
| My understanding was that this sort of mixing was allowed except for varargs
| functions, or prototyped functions with char/float/short parameters, but I
| was recently told I was wrong.  Could someone clear it up for me.

You are right.  In the ANSI committee, this rule is refered to as the
Miranda Rule, after the Miranda case in the US legal system.  The
Miranda part comes from:

	You have the right to a prototype.  If you cannot afford a
	prototype, one will be appointed to you by the compilation
	system.

Section 3.3.2.2 of the standard reads in part:

	   If the expression that denotes the called function has a
	type that does not include a prototype, the integral
	promotions are perfomed on each argument and arguments that
	have type 'float' are promoted to 'double'.  These are called
	the 'default argument promotions'.  If the number of arguments
	does not agree with the number of parameters, the behavior is
	undefined.  If the function is defined with a type that does
	not include a prototype, and the types of the argument after
	promotion are not compatible with those of the parameters
	after promotion, the behavior is undefine.  If the function is
	define with a type that includes a prototype, and the types of
	the arguments after promotion are not compatible with the
	types of the parameters, or if the prototype ends with an
	ellipsis (, ...), the behavior is undefined.

| Can a non-prototyped function be called with a prototype in scope?
| I assume not.

Actually, yes, as long as the function does not have char/short/float
arguments, or a variable argument list.  In fact, this is the typical
way code is prototyped, by first changing the headers to have
prototypes, and then sometime in the future, going back and changing
the function definitions.  This way is especially useful when you have
some ANSI compilers you are porting to and some K&R classic compilers.
Only the headers (and the varadic functions) need __STDC__ ifdefs.

Section 3.5.4.3 of the standard reads in part (talking about function
types being compatible):

	... If one type has a parameter type list and the other type
	is specified by a function definition that contains a
	(possibly empty) identifier list, both shall agree in the
	number of parameters, and the type of each prototype parameter
	shall be compatible with the type that results from the
	application of the default argument promotions to the type of
	the corresponding identifier.  (For each parameter declared
	with function or array type, its type for these comparisons is
	the one that results from converion to a pointer type, as in
	section 3.7.1.  For each parameter declared with qualified
	type, its type for these comparisons is the unqualified
	version of its declared type.)
--
Michael Meissner	email: meissner@osf.org		phone: 617-621-8861
Open Software Foundation, 11 Cambridge Center, Cambridge, MA, 02142

You are in a twisty little passage of standards, all conflicting.