Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!seismo!hao!woods From: woods@hao.UUCP (Greg Woods) Newsgroups: comp.lang.c Subject: Re: Bug converting unsigned to double in BSD 4.[23] Message-ID: <295@hao.UUCP> Date: Wed, 19-Nov-86 21:03:23 EST Article-I.D.: hao.295 Posted: Wed Nov 19 21:03:23 1986 Date-Received: Wed, 19-Nov-86 23:00:38 EST References: <213@cartan.Berkeley.EDU> <618@hadron.UUCP> Organization: High Altitude Obs./NCAR, Boulder CO Lines: 54 Summary: Other 68K bugs In article <618@hadron.UUCP>, jsdy@hadron.UUCP (Joseph S. D. Yao) writes: > In article <213@cartan.Berkeley.EDU> ballou@brahms (Kenneth R. Ballou) writes: > >main () > >{ > > printf ("%u\n", ~ ((unsigned) 0)); > > printf ("%lf\n", (double) (~ ((unsigned) 0))); > > printf ("%lf\n", 4294967295.0); /* surely double is large enough for this? */ > >} > >% bug > >4294967295 > >-1.000000 > >4294967295.000000 > > This didn't work (actually, worked as expected!) on our ISI 68000- > based machine. I've seen something similar, and I think your bug probably has to do with the same thing. On a VAX, and every machine I've worked on EXCEPT the ISI-68K, the first 32 bits of a double form a float. Not true on the 68000. Consider the following trivial C program: main() { float f=1.0; test1(f); exit(0); } test1(f) float f; { printf("test1: f=%f\n",f); test2(&f); } test2(f) float *f; { printf("test2: f=%f\n",*f); What one observes is that on the VAX, both printf's print the same value, as they do on a Pyramid 90X, but on the ISI 68020/68881 (both with and without the -f option to enable use of the 68881) they are different. Since I was curious, I ran the same program on a Sun-2 and a Sun-3 that I have access to. Different values there too. The reason is that according to the C standard, when f is passed to test1, it is converted to a double and placed on the stack. When test1 calls test2, it DOESN'T CONVERT the stacked value back to a float before calling test2, so that test2 is passed the address of something that is really a double, not a float as declared in the code. This is a BUG, and it has bitten us badly in many big libraries where we have little stubs designed to allow the calling of FORTRAN routines from C without having to observe FORTRAN calling conventions, e.g.: sub(f) float f; { sub_(&f); } This allows C calls like "sub(2.)" which would otherwise require the creation of a temporary variable like "float temp=2; sub_(&temp)". I maintain this is a BUG, because I specifically declare that what I am passing the address of is a float, when in fact it's a double. --Greg -- {ucbvax!hplabs | decvax!noao | mcvax!seismo | ihnp4!seismo} !hao!woods CSNET: woods@ncar.csnet ARPA: woods%ncar@CSNET-RELAY.ARPA