Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!uwm.edu!uakari.primate.wisc.edu!ames!sgi!davea@quasar.wpd.sgi.com From: davea@quasar.wpd.sgi.com (David B. Anderson) Newsgroups: comp.sys.sgi Subject: Re: Array boundary checking & Fortran <> C translators Message-ID: <49566@sgi.sgi.com> Date: 2 Feb 90 19:43:58 GMT References: <90Jan25.135818est.57895@ugw.utcs.utoronto.ca> <65973@aerospace.AERO.ORG> Sender: davea@quasar.wpd.sgi.com Reply-To: davea@quasar.UUCP (David B. Anderson) Organization: Silicon Graphics, Inc., Mountain View, CA Lines: 50 In article <65973@aerospace.AERO.ORG> tak@aero.UUCP (Michael L. Takayama) writes: [stuff deleted, some text below rearranged to save space....] >In certain cases, floats do *not* pass correctly to REALs. This >problem does not occur with ints to INTEGERs nor with doubles to >DOUBLE PRECISIONs. >main() >{ double a; float b; int c; > a = 1234.5678; /* Assign values. */ > b = 9876.1234; > c = 121162; > /* Call C routine which calls Fortran routine. */ > subtestc(a, b, c); >} >*** subtest.c *** >subtestc(a, b, c) >double a; >float b; >int c; >{ float temp; > temp = b; /* This is my work-around. */ > /* Call the Fortran routine. */ > subtest_(&a, &b, &c, &temp); >} [stuff deleted] >Maybe I am doing something illegal here and just got lucky with the ^^^^^^^^^^^^^^^^^^^^^^^ Yes, you are. >ints and doubles passing correctly (I don't think so - I have >about 60 routines mixing C and Fortran which *do* work correctly), but I >notified the Hotline and they think it is an undiscovered bug in >the Fortran compiler. No bug here. The problem is the way automatic conversions of float to double are treated in K&R C (See K&R 1, page 205 ``formal parameters declared float have their declaration adjusted to read double''). Parameter b in subtestc is called a float but *is really a double*. Thus, subtest_(&a,&b,&c,&temp) passes a pointer (&b) which appears to be a pointer to a float but is really a pointer to a double. Consequently dereferencing the pointer results in garbage. In ANSI C, the behaviour is required to be different: your code would work with an ANSI C compiler. The reason is that while there would be an argument which was a float-converted-to-double, b would be a float and the compiler would generate an assignment in subtestc's entry to assign and convert the argument to the float b. (ANSI sec 3.5.4.3, 3.7.1, 3.3.2) Hope this helps. Regards, [ David B. Anderson Silicon Graphics (415)335-1548 davea@sgi.com ]