[comp.os.minix] float VS double: The return...

ARCHER@segin4.segin.fr (04/10/90)

Christoph van Wuellen <HBO043@DJUKFA11.BITNET> says:

CvW> ... WHAT ABOUT
CvW> test(a) float a;
CvW> {
CvW> test1(&a);
CvW> }
CvW> This certainly passes a pointer to a double, and this can't be changed.
CvW> So I ask the C Syntax experts - what do you think a compiler should do
CvW> in both cases?

I don't think for my compiler :-), but a compiles as a double (sizeof being 8),
and *a in test1 has nothing near the same value as a in test:

    test(a) float a;
    {
    a = 0.1;
    printf("%f\n", a);
    test1(&a);
    }

    test1(a) float *a;
    {
    printf("%f\n", *a;
    }

said:

0.1
1.45000


It seems that most compilers do the same kind of thing. So if your compiler
enables the user to do some mistakes, you'll lose portability: The program will
work compiled with C68, and not with any other compiler. What's more important?


    Vincent Archer

Replies to: archer%segin4.segin.fr@prime.com, NOT archer@segin4.segin.fr

tim@nucleus.amd.com (Tim Olson) (04/11/90)

In article <16383@nigel.udel.EDU> ARCHER@segin4.segin.fr writes:
| I don't think for my compiler :-), but a compiles as a double (sizeof being 8),
| and *a in test1 has nothing near the same value as a in test:
| 
|     test(a) float a;
|     {
|     a = 0.1;
|     printf("%f\n", a);
|     test1(&a);
|     }
| 
|     test1(a) float *a;
|     {
|     printf("%f\n", *a;
|     }
| 
| said:
| 
| 0.1
| 1.45000
| 
| 
| It seems that most compilers do the same kind of thing. So if your compiler
| enables the user to do some mistakes, you'll lose portability: The program will
| work compiled with C68, and not with any other compiler. What's more important?

If you want to start progressing towards ANSI compatibility, then this
must be fixed.  The Standard says (in the Rationale Section):

	Some current implementations rewrite the type of a (for
	instance) |char| parameter as if it were declared |int|, since
	the argument is known to be passed as an |int| (in the absence
	of prototypes).  The Standard requires, however, that the
	received argument be converted "as if" by assignment upon
	function entry.  Type rewriting is thus no longer permissible.


This means that in:

f(c, f)
char c;
float f;
{
	.
	.
sizeof c should be 1 and sizeof f should be equal to sizeof(float).

	-- Tim Olson
	Advanced Micro Devices
	(tim@amd.com)

ath@prosys.se (Anders Thulin) (04/11/90)

In article <29812@amdcad.AMD.COM> tim@amd.com (Tim Olson) writes:
>
>  [ quote ANSI Rationale deleted ]
>
>This means that in:
>
>f(c, f)
>char c;
>float f;
>{
>	.
>	.
>sizeof c should be 1 and sizeof f should be equal to sizeof(float).

No. The ANSI C standard also tries very hard not to introduce backward
incompabilities.  The example above works just the way K&R says:
c becomes an int, and f a double by widening, provided there isn't
a new-style definition of f lurking in some corner.

In the presence of a new-style definition, like

	f(char c, float f);

c would indeed be a char and f a float. 

I can't quote the ANSI gospel, but K&R, 2nd ed, Section A7.3.2 Function
calls, p.201-202 provides more info.

-- 
Anders Thulin		ath@prosys.se   {uunet,mcsun}!sunic!prosys!ath
Telelogic Programsystem AB, Teknikringen 2B, S-583 30 Linkoping, Sweden

tim@nucleus.amd.com (Tim Olson) (04/11/90)

In article <460@helios.prosys.se> ath@prosys.se (Anders Thulin) writes:
| No. The ANSI C standard also tries very hard not to introduce backward
| incompabilities.  The example above works just the way K&R says:
| c becomes an int, and f a double by widening, provided there isn't
| a new-style definition of f lurking in some corner.
| 
| In the presence of a new-style definition, like
| 
| 	f(char c, float f);
| 
| c would indeed be a char and f a float. 
| 
| I can't quote the ANSI gospel, but K&R, 2nd ed, Section A7.3.2 Function
| calls, p.201-202 provides more info.

This section really only discusses promotion of arguments by the
caller, which should be done.  However, I was referring to
X3J11/88-159 (December 7 draft, just before ratification), which
explicitly states (as a noted QUIET CHANGE) that the received, widened
argument must be narrowed upon entry, and that type rewriting is not
allowed.

I checked it with two ANSI-conforming compiler we have here (MetaWare
HighC and gcc with -ansi -pedantic flags), and they both agree with
this.


	-- Tim Olson
	Advanced Micro Devices
	(tim@amd.com)

HBO043%DJUKFA11.BITNET@cunyvm.cuny.edu (Christoph van Wuellen) (04/11/90)

The point is:
in the sequence
test (a) float a;
{
....
}

I change the ,,float'' to double as soon the argument declarations have
been processed. The same promotions occur for char==>int, short==>int etc.

Now, I am of the opinion that this is correct, although GCC (which I use
as a reference compiler when I am not sure) converts the double back to
a float in the startup code of the function if its address is used somewhere.

I think this is a big mess. It really should be a syntax error to declare
a ,,char'' argument of a function etc. (This might not be true if you use
prototypes that might suppress the default promotions).

My opinion at the moment is that I should not change this in the compiler.
/Christoph van Wuellen
P.S. with char/int it is the same problem if you don't assume that you
can retrieve the char in the low order bits of the int (I wouldn't put
such an assumption into the front end of a compiler)

bill@flash.UUCP (William Swan) (04/12/90)

In article <16383@nigel.udel.EDU> ARCHER@segin4.segin.fr writes:
>CvW> ... WHAT ABOUT
>CvW> test(a) float a;
>CvW> {
>CvW> test1(&a);
>CvW> }
>CvW> This certainly passes a pointer to a double, and this can't be changed.
>CvW> So I ask the C Syntax experts - what do you think a compiler should do
>CvW> in both cases?

I've come a little late into this discussion, and I'm no C Syntax Expert[tm],
but I've run into this before.  Oddly, this came up on a local BBS this past
weekend.

The description of the ANSI C standard in K&R 2nd Ed. says, in essence, that
float parameters declared "old-style" are promoted to double, those declared
"new-style" are not.  (K&R C, 2nd Ed. ,p 202, section A7.3.2 Function Calls)  

In other words:
	main() {
		float f; 
		test(&f);
		}
	test(f)
	float *pf; 
		{
		printf(..., *pf);
		}
will fail, but:
	main() {
		float f; 
		test(&f);
		}
	test(float *pf) {
		printf(..., *pf);
		}
will not.

-- 
Bill Swan      bill@Summation.WA.COM          Send postal address for info:
	Innocent but in prison in Washington State for 13.5 years (or more):
	Ms. Debbie Runyan: incarcerated 01/1989, scheduled release 07/2002.
	                   In now:  1 year,   2 months,  3 weeks,  1 day.