yuleat@prlhp1.prl.philips.co.uk (yuleat) (08/15/89)
Now that I've got your attention, why not consider the following piece of code (which has nothing to do with nude vicars!) : #include <stdio.h> main() { float x= 0.1234; fn1(x); } fn1(x) float x; { float y= x; fn2(&x, &y); } fn2(x, y) float *x, *y; { printf("In fn2 values are x= %f & y= %f\n", *x, *y); } The interesting thing is that on both the compilers (HP & Apollo) I've tried this on, the values printed out by the printf() are different. Specifically, x is gibberish, whilst y is correct (0.1234). I believe that the reason for this is that x in main() is converted to a double as it is passed to fn1(), thus the pointer that is passed to fn2() is really a pointer to a double and hence when it is de-refernced as a pointer to a float, it gets the "wrong" answer. What I would like to know is whether this is what the compiler should do (I've looked in K&R and I couldn't find anything that addressed this problem specifically). ---------------------------------------------------------------------- Andy Yule Philips Research Labs, (yuleat@prl.philips.co.uk) Redhill, England. ======================================================================
dan@oresoft.uu.net (Daniel Elbaum) (08/18/89)
The pANS requires that floats be promoted to double for function calls unless the function is prototyped as taking float arguments. Classic C doesn't constrain compilers to promote. -- Spa link snot the temper tent, a few cannery doubt lowed. ({uunet,tektronix,reed,sun!nosun,osu-cis,psu-cs}!oresoft!(dan)@oresoft.uu.net)
walter@hpclwjm.HP.COM (Walter Murray) (08/18/89)
Andy Yule writes: > #include <stdio.h> > main() > { > float x= 0.1234; > fn1(x); > } > fn1(x) > float x; > { > float y= x; > fn2(&x, &y); > } > fn2(x, y) > float *x, *y; > { > printf("In fn2 values are x= %f & y= %f\n", *x, *y); > } > [Conjecture as to why the first value printed is gibberish] > What I would like to know is whether this is what the compiler > should do (I've looked in K&R and I couldn't find anything > that addressed this problem specifically). A number of C implementations do this. In fn1(), the compiler is rewriting the type of x to double, knowing that that's how it is going to be passed. All behavior will be exactly as though you had written 'double x' rather than 'float x'. Try printing sizeof(x) and you will see that it is equal to sizeof(double), not sizeof(float). Your understanding of what is happening is correct. Some compilers do this type rewriting for integral parameter types as well as for floating types, although HP only does it for floating types. You will be glad to know that the dpANS outlaws this behavior. Run your program on an ANSI-conforming compiler and it will print 0.123400 for both *x and *y. If you have a copy of the dpANS, see section 3.7.1 of the Rationale. Walter Murray ----------
ccdn@levels.sait.edu.au (DAVID NEWALL) (08/18/89)
In article <960@prlhp1.prl.philips.co.uk>, yuleat@prlhp1.prl.philips.co.uk (yuleat) writes: > Now that I've got your attention, why not consider the following > piece of code (which has nothing to do with nude vicars!) : > > [ code deleted ] > > The interesting thing is that on both the compilers (HP & Apollo) > I've tried this on, the values printed out by the printf() are > different. Specifically, x is gibberish, whilst y is correct > (0.1234). I believe that the reason for this is that x in main() > is converted to a double as it is passed to fn1(), thus the pointer > that is passed to fn2() is really a pointer to a double and hence > when it is de-refernced as a pointer to a float, it gets the "wrong" > answer. Page 41, K&R: "Notice that all float's in an expression are converted to double; all floating point arithmetic in C is done in double precision." Page 42, K&R: "Since a function argument is an expression, type conversions also take place when arguments are passed to functions: in partuclar, ... float becomes double. This is why we have declared function arguments to be ... double even when the funciton is called with ... float." The question is not why x in main() is passed as a double, but rather, why the compiler doesn't warn you when you declare x in fn1() as a float. For the record, I get the same result on an NCR Tower 32/400 (Tower OS 2.01) and a Sun 3/60 (SunOS 4.0.3) David Newall Phone: +61 8 343 3160 Unix Systems Programmer Fax: +61 8 349 6939 Academic Computing Service E-mail: ccdn@levels.sait.oz.au SA Institute of Technology Post: The Levels, South Australia, 5095
devine@shodha.dec.com (Bob Devine) (08/22/89)
In article <960@prlhp1.prl.philips.co.uk>, yuleat@prlhp1.prl.philips.co.uk (yuleat) writes: > fn2(x, y) > float *x, *y; > { > printf("In fn2 values are x= %f & y= %f\n", *x, *y); > } > > What I would like to know is whether this is what the compiler > should do (I've looked in K&R and I couldn't find anything > that addressed this problem specifically). Check out the sections on parameter widening. The floats (likely these are 4 bytes) are being widened to doubles (8 bytes) so when you use a `float *' you are only getting 1/2 the number. On some machines a hardware check for a valid floating point number is made so if you had bad luck to select the wrong bit pattern the program would have dumped with a very misleading error! Bob Devine
lmb@ibmpa.UUCP (Larry Breed) (08/24/89)
In article <1989Aug17.191545.13040@oresoft.uu.net> dan@oresoft.uu.net (Daniel Elbaum) writes: > >The pANS requires that floats be promoted to double for >function calls unless the function is prototyped as >taking float arguments. Classic C doesn't constrain >compilers to promote. K&R does indeed require compilers to promote floating args to double. This matches the pANS when there's no prototype visible. -- Larry Breed inet: lmb%ibmsupt@uunet.uu.net uucp: uunet!ibmsupt!lmb (415) 855-4460
dan@oresoft.uu.net (Daniel Elbaum) (08/25/89)
In article <1827@ibmpa.UUCP> lmb@ibmpa.UUCP (Larry Breed) writes: :In article <1989Aug17.191545.13040@oresoft.uu.net> dan@oresoft.uu.net (Daniel Elbaum) writes: :>... Classic C doesn't constrain :>compilers to promote. : :K&R does indeed require compilers to promote floating args to double. :This matches the pANS when there's no prototype visible. True enough, though not all compilers obeyed the constraint. My dog peed on that page of K&R. -- Spa link snot the temper tent, a few cannery doubt lowed. ({uunet,tektronix,reed,sun!nosun,osu-cis,psu-cs}!oresoft!(dan)@oresoft.uu.net)