[net.lang.c] Help me out on Float Double Parameters

gnu@hoptoad.uucp (John Gilmore) (04/09/86)

In article <3439@sun.uucp>, guy@sun.uucp (Guy Harris) writes:
> Mr. Koenig is correct.  According to the August 11, 1985, X3J11 draft:
> 
> 	C3.2.2 Function calls
> 
> 	... Also, *if no function prototype declarator is in scope*, the
> 	integral promotions are performed and arguments that have type
> 	"float" are promoted to "double".  ("italics" mine)
> 
> 	... If a function prototype declarator is in scope, the arguments
> 	are compared with the formal parameters.  ...The types must be
> 	such that each formal parameter may be initialized by the
> 	coresponding argument, and the arguments are converted
> 	accordingly.

I think the above applies to CALLS of the function, not DEFINITIONS of the
function.  But let me see if I understand how this works.  If I write:

	foo(float x) {...}		/* DEFINE */

then (if this is legal, which I don't know) it expects it as float.
(Of course, any time the DEFINITION expects float, there had better
be a DECLARATION in the callers' routines that matches.)

	foo(x)  float x;  {...}		/* DEFINE */

I presume for compatability it must expect double.

	foo(float x);			/* DECLARE */

	foo(x)  float x;  {...}		/* DEFINE */

Now maybe it can expect float?  Suppose the declaration and the
definition are separated by a few pages, or the declaration is in
a header file -- how will you know what the routine expects?

	foo(float x)  float x;  {...}	/* DEFINE */

Is this legal?  Does it take float or double?

Is the same true if you declare an argument char or short?  Does it
avoid the widening to int on the stack?

I can see that no matter what the answers to the above questions, the C
standardization process is not making C any simpler to use.  Sigh.
Feeping creatureism is leaving its trail of turds.
-- 
John Gilmore  {sun,ptsfa,lll-crg,ihnp4}!hoptoad!gnu   jgilmore@lll-crg.arpa
			     Post no bills.

guy@sun.uucp (Guy Harris) (04/09/86)

> I think the above applies to CALLS of the function, not DEFINITIONS of the
> function.

Of course it applies to calls; definitions generate no code and therefore
don't involve widening.

> But let me see if I understand how this works.  If I write:
> 
> 	foo(float x) {...}		/* DEFINE */
> 
> then (if this is legal, which I don't know)

It is legal.  See the example on p. 59 of the August 11, 1985 draft for the
function "max":

	extern int max(int a, int b)
	{
		return a > b ? a : b;
	}

> it expects it as float.
> (Of course, any time the DEFINITION expects float, there had better
> be a DECLARATION in the callers' routines that matches.)

Yes, but then again if you define the external variable "foo" as "char *",
or define the external function "getenv" as returning "char *", any module
using one of them must declare it as "char *" in order to be correct.

> 	foo(x)  float x;  {...}		/* DEFINE */
> 
> I presume for compatability it must expect double.

C.3.2.2 Function calls

	...in particular, the number and types of arguments are not
	compared with those of the formal parameters in a function
	definition that does not include a function prototype
	declarator.

The above is such a definition (a function prototype declarator has type
names inside the parentheses, and this definition doesn't), so the matching
declaration would be "int foo();" and no type-checking would be done.

> 	foo(float x);			/* DECLARE */
> 
> 	foo(x)  float x;  {...}		/* DEFINE */
> 
> Now maybe it can expect float?

C.7.1 Function definitions

	...If a function prototype is in scope when the function is
	defined, a semantically equivalent prototype must be in scope
	everywhere the function is called.

I interpret this as meaning that if a prototype is in scope when the
function is defined, whether the prototype is part of the definition or not,
the function has a prototype; therefor, it can expect "float".

> Suppose the declaration and the definition are separated by a few pages,
> or the declaration is in a header file -- how will you know what the
> routine expects?

That's obvious - you read the manual page (or whatever the author of the
function supplied).  The C language does not enforce good documentation or
coding style.

> 	foo(float x)  float x;  {...}	/* DEFINE */
> 
> Is this legal?  Does it take float or double?

C.7.1 Function definitions

	...If the declarator is a function prototype declarator, no
	declaration list may follow.

No, it's not legal, so the second question has no answer.

> Is the same true if you declare an argument char or short?  Does it
> avoid the widening to int on the stack?

C.3.2.2 Function calls

	...Also, if no function prototype declarator is in scope, the
	integral promotions are performed...

Presumably, then, if a prototype *is* in scope, the integral promotions are
*not* performed.  Yes, it avoids the widening.

> I can see that no matter what the answers to the above questions, the C
> standardization process is not making C any simpler to use.  Sigh.
> Feeping creatureism is leaving its trail of turds.

Given that the notion that the types of formal and actual arguments must be
of similar type seems to be extremely hard for some programmers to
understand (some of them whine most piteously when you inform them that they
must cast NULL or 0 to a pointer of the appropriate type), and given that
many logical errors in coding manifest themselves as type mismatches between
formal and actual parameters to functions (which would be detected at
compile time if a function prototype is in scope), I see no evidence
whatsoever for your claim.  If function prototypes are used, it will make
getting C code right much simpler.  Yes, the rules have a few complications,
but those are hardly the excreta of the standardization process; if ANSI C
didn't have to include most currently legal C code in the set of legal ANSI
C code, things could be much simpler.  (One hopes, BTW, that it will be
legal to give a warning if a function is declared by "default", i.e. if it
gets declared as "int foo()" by calling it.  This will encourage people to
start properly declaring functions that they use.)

In many ways, I mistrust "simple"-to-use languages; they encourage people
not to think about what they're writing.
-- 
	Guy Harris
	{ihnp4, decvax, seismo, decwrl, ...}!sun!guy
	guy@sun.arpa	(yes, really)