[comp.lang.c] new style declarations OK for old style definitions?

tmb@ai.mit.edu (Thomas M. Breuel) (04/03/91)

K&R/2 is a little vague on the following question: under what
circumstances is it legal to declare using new-style syntax a
separately compiled function that was compiled with an old-style
definition. 

Is it sufficient to use only promoted arguments in the new-style
declaration?

Conceivably, the whole calling sequence for old style and new style
definitions could differ. Is it legal for the compiler to choose
completely incompatible calling sequences for old-style and new-style
declarations? It would certainly be desirable, since new-style
declarations seem to allow for significant optimizations that aren't
possible with old-style declarations.

This is a frequent problem if you have old library binaries and
sources but want the extra type checking from an ANSI compiler.

				Thanks, Thomas.

grogers@convex.com (Geoffrey Rogers) (04/03/91)

In article <14590@life.ai.mit.edu> tmb@ai.mit.edu writes:
>K&R/2 is a little vague on the following question: under what
>circumstances is it legal to declare using new-style syntax a
>separately compiled function that was compiled with an old-style
>definition. 
>
>Is it sufficient to use only promoted arguments in the new-style
>declaration?

Yes. If you don't use the default promotion types you will have
problems. If you have a old-style definition of:

int xyz(a,b,c)
	char  a;
	short b;
	float c;
{
	return 0;
}

The new-style declaration is:

extern int xyz(int a, int b, double c);

>Conceivably, the whole calling sequence for old style and new style
>definitions could differ. Is it legal for the compiler to choose
>completely incompatible calling sequences for old-style and new-style
>declarations? 

Yes. If you said one thing and did another the compiler would have no way
of known that you were lying to it, unless the new-style declaration was also
in the same file as the old-style definition.


+------------------------------------+---------------------------------+
| Geoffrey C. Rogers   		     | "Whose brain did you get?"      |
| grogers@convex.com                 | "Abbie Normal!"                 |
| {sun,uunet,uiucdcs}!convex!grogers |                                 |
+------------------------------------+---------------------------------+

steve@taumet.com (Stephen Clamage) (04/05/91)

tmb@ai.mit.edu (Thomas M. Breuel) writes:

>K&R/2 is a little vague on the following question: under what
>circumstances is it legal to declare using new-style syntax a
>separately compiled function that was compiled with an old-style
>definition. 

>Is it sufficient to use only promoted arguments in the new-style
>declaration?

You must not use char, short or float arguments in any of the
declarations (nor in the ultimate function header).  The function
must not accept a variable number of parameters, and the prototype
must not include the ellipsis (...).  These rules will allow
portability of the code.

>Conceivably, the whole calling sequence for old style and new style
>definitions could differ. Is it legal for the compiler to choose
>completely incompatible calling sequences for old-style and new-style
>declarations?

Not when the above rules are followed.  If you violate any of these rules,
a conforming compiler is allowed to use different calling sequences.

>It would certainly be desirable, since new-style
>declarations seem to allow for significant optimizations that aren't
>possible with old-style declarations.

Yes.  Prototyped functions may use different parameter passing for
chars, shorts, and floats, and would do so if they are more efficient.
In particular, when a function is declared with an ellipsis, the compiler
may use a different method of passing the extra parameters than if you
call a non-prototyped function.

>This is a frequent problem if you have old library binaries and
>sources but want the extra type checking from an ANSI compiler.

>				Thanks, Thomas.
-- 

Steve Clamage, TauMetric Corp, steve@taumet.com

gwyn@smoke.brl.mil (Doug Gwyn) (04/05/91)

In article <14590@life.ai.mit.edu> tmb@ai.mit.edu writes:
>Conceivably, the whole calling sequence for old style and new style
>definitions could differ. Is it legal for the compiler to choose
>completely incompatible calling sequences for old-style and new-style
>declarations?

No, a conforming implementation must support intermixing of old-style
and prototype-style function linkage, so long as compatible types are
involved.  Basically that means that an exception can be made for
prototypes only when at least one parameter or the return value has a
type different from those obtained by default widening conventions,
and also the linkage can differ for the ",..." style of prototype no
matter what the types of the fixed arguments.

bliss@sp64.csrd.uiuc.edu (Brian Bliss) (04/05/91)

In article <14590@life.ai.mit.edu>, tmb@ai.mit.edu (Thomas M. Breuel) writes:
|> K&R/2 is a little vague on the following question: under what
|> circumstances is it legal to declare using new-style syntax a
|> separately compiled function that was compiled with an old-style
|> definition. 
|> 
|> Is it sufficient to use only promoted arguments in the new-style
|> declaration?
|> 
|> Conceivably, the whole calling sequence for old style and new style
|> definitions could differ. Is it legal for the compiler to choose
|> completely incompatible calling sequences for old-style and new-style
|> declarations? It would certainly be desirable, since new-style
|> declarations seem to allow for significant optimizations that aren't
|> possible with old-style declarations.
|> 

K&RII says (I'm reciting from memory, my book's at home):

If a function which is declared new-style is called, and
no prototype for it exists in the current scope, the 
promoted type of the actual argument must agree exactly
with the unpromoted type of the formal argument.

Since the compiler could not know whether the function
was declared new-style or old-style (burp :-), it must
use the same calling conventions for both.

you are asking the converse, ig you can call an old-style function
with a (new-style) prototype existing for it in the current scope, but I
believe it is implicitly specified that using a prototype
with promoted arguments is O.K.

My question is why?  just eliminate the prototype, or if
you need the parameter type checking, change the definition
of your function to be new-style, and change all of the formal
arguments to their promoted types.  Then you are following
the ANSI standard to the letter.

bb

mcdaniel@adi.com (Tim McDaniel) (04/08/91)

The original question was about mixing an old-style, unprototyped
function definition in one file with a new-style, prototyped
declaration in another.

In article <1991Apr03.141849.26379@convex.com> grogers@convex.com
(Geoffrey Rogers) writes:

   In article <14590@life.ai.mit.edu> tmb@ai.mit.edu writes:
   > Is it sufficient to use only promoted arguments in the new-style
   > declaration?

   Yes. If you don't use the default promotion types you will have
   problems.

Exactly.

   >Is it legal for the compiler to choose
   >completely incompatible calling sequences for old-style and new-style
   >declarations?

   Yes.

No.  Section 3.5.4.3 of the Standard defines compatability of function
types.  An old-style function declaration is compatable with a
new-style declaration, if the new-style uses promoted arguments and
doesn't use ellipses.

Thus, with care, you CAN mix new-style with old-style.  Because of the
care required, I do not recommend such mixing.

--
   "Of course he has a knife.  We all have knives.  It's 1183, and we're
   all barbarians."
Tim McDaniel                 Applied Dynamics Int'l.; Ann Arbor, Michigan, USA
Internet: mcdaniel@adi.com                UUCP: {uunet,sharkey}!amara!mcdaniel