Float Double Parameters
aglew at ccvaxa.UUCP
aglew at ccvaxa.UUCP
Thu Mar 27 14:34:00 AEST 1986
Mouse Parker found a bug in Sun C's treatment of float parameters.
His entire letter is reproduced below, since it was from another newsgroup.
> First and foremost, get rid of the stupid promotion to doubles! I
>have considered this a misfeature ever since I heard of it.
>Tangentially to this topic, does X3J11 have anything to say on this
>matter?
X3J11 says "arguments that have type float are promoted to double". Too bad.
The bug is real, but you've only been bitten by it because you are following
bad programming practice in trying to make a parameter do two jobs. It has
already imported a value into the called function, and now you are trying
to give it another job to do by reading something into it. A compiler that
could do a good liveness analysis (hard to do in C admittedly) should
probably be the one to reuse the space, not you. The C practice of reusing
parameters as temporaries should only really be permitted when the new
values are related to the original value of the parameter, as, for example,
in using a char* parameter to walk down a string.
Squeak?
Here is der Mouse's letter in full.
>/**** ccvaxa:fa.sun-spots / mouse at mcgill-vi / 10:06 pm Mar 17, 1986 ****/
>From: mouse at mcgill-vision.UUCP (der Mouse)
>Subject: Sun cc bug (Sun UNIX 2.0)
>
>Problem:
> Taking the address of "float" formal function parameters does not
> work right.
>
>Repeat-by:
> Try the following program on your favorite Sun:
>
> main()
> {
> float r;
>
> r = 90;
> foo(r);
> }
>
> foo(r)
> float r;
> {
> while (scanf("%f",&r) == 1)
> { printf("%g\n",r);
> }
> }
>
> Compile. Run. Enter (for example) 90 and notice the printed value
>is nowhere near 90. Try other values. Generally bad results.
>
>Analysis/discussion:
>
> I compiled the above with -S and looked at the assembly code. The
>problem seems to be related to the way the C compiler promotes floats to
>doubles in function calls. That is, foo() knows that its caller is
>really going to pass a double rather than a float, so it behaves as if r
>were a double. The trouble is, when we take the address of r, which is
>supposedly a float variable, the pointer actually points to a double!
>This is hardly the behaviour I expect from applying the "&" operator to
>a variable which has been declared "float".
>
>Immediate fix:
>
> All I have is a workaround....declare your formal parameters as
>doubles rather than floats, then make sure that when you take the
>address of one that you realize you are taking the address of a double
>and not a float! The above code works if changed as follows:
>
> foo(r)
> double r;
> {
> while (scanf("%lf",&r) == 1) /* note we use %lf not %f */
> { printf("%g\n",r);
> }
> }
>
> I suspect, but have not yet verified, that the same problem exists
>on our VAXen as well, where it is masked because you can get away with
>treating a pointer to a double as if it were a pointer to a float and
>all that will happen is the extra precision will be unchanged (the
>exponent fields are the same size). This is not true on the Sun, which
>uses a different floating-point format.
>
>Longterm recommendations for C compiler writers:
>
> First and foremost, get rid of the stupid promotion to doubles! I
>have considered this a misfeature ever since I heard of it.
>Tangentially to this topic, does X3J11 have anything to say on this
>matter?
>
> If you can't or won't, then make sure that functions which take
>"float" arguments make sure there is a valid "float" somewhere around
>(this may mean generating another temporary variable and copying the
>argument into it).
>
> der Mouse
More information about the Comp.lang.c
mailing list