Bug converting unsigned to double in BSD 4.[23]

Greg Woods woods at hao.UUCP
Thu Nov 20 12:03:23 AEST 1986


In article <618 at hadron.UUCP>, jsdy at hadron.UUCP (Joseph S. D. Yao) writes:
> In article <213 at cartan.Berkeley.EDU> ballou at 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 at ncar.csnet  ARPA: woods%ncar at CSNET-RELAY.ARPA



More information about the Comp.lang.c mailing list