karron@KARRON.MED.NYU.EDU (11/14/90)
I am working on modifying a software package written to run in the older SGI compiler environment. I have just had LOTS of problems that I have finally nailed down to mixing old and new argument styles. Seems you can't have newstyle argument lists (ANSI) receiving parameters from old styles,non prototyped code. I first tried to write all my new stuff in ANSI code, but it would always get float (Coord) arguments wrong. Finally, I had to recode my new subroutines in old C style arguments. ANSI C:void MyNewSubroutine(Coord x,Coord y,Coord z) { do da, do that thing } K & R 1: void TheOldWayToAvoid(x,y,z) Coord x,y,z; { do da, do that thing } It seems a bit much to be forced to 1)rewrite ALL the old code in ANSI style headers or 2) Write new stuff with old style headers. This is something that should be fixed. There is a lot of code out there that needs work, and I should not have to write new stuff in old style c. dan. +-----------------------------------------------------------------------------+ | karron@nyu.edu (mail alias that will always find me) | | Dan Karron | | . . . . . . . . . . . . . . New York University Medical Center | | 560 First Avenue \ \ Pager <1> (212) 397 9330 | | New York, New York 10016 \**\ <2> 10896 <3> <your-number-here> | | (212) 340 5210 \**\__________________________________________ | | Please Note : Soon to move to dan@karron.med.nyu.edu 128.122.135.3 (Nov 1 )| +-----------------------------------------------------------------------------+
guy@auspex.auspex.com (Guy Harris) (11/17/90)
>Seems you can't have newstyle argument lists (ANSI) receiving parameters >from old styles,non prototyped code. > >I first tried to write all my new stuff in ANSI code, but it would >always get float (Coord) arguments wrong. ... >This is something that should be fixed. Fine, hop in your time machine, go back to the ANSI C meetings where they decided that if you have a routine declared with prototypes with arguments that are "float", that it really gets passed "float"s, not "double"s, and convince them otherwise. That should fix it.... If that's not possible, you're out of luck unless you can convince SGI or whoever to have "float" just mean "double", which is unlikely given the number of other things it'll probably break.... If you have a routine that is to have prototypes, is to be passed floating-point arguments, and is to be called by old-style C, make its arguments "double" - even if that means not giving them type "Coord".
karron@KARRON.MED.NYU.EDU (11/17/90)
>>Seems you can't have newstyle argument lists (ANSI) receiving parameters >>from old styles,non prototyped code. >> >>I first tried to write all my new stuff in ANSI code, but it would >>always get float (Coord) arguments wrong. > >... > >>This is something that should be fixed. > >Fine, hop in your time machine, go back to the ANSI C meetings where >they decided that if you have a routine declared with prototypes with >arguments that are "float", that it really gets passed "float"s, not >"double"s, and convince them otherwise. That should fix it.... > >If that's not possible, you're out of luck unless you can convince SGI >or whoever to have "float" just mean "double", which is unlikely given >the number of other things it'll probably break.... > >If you have a routine that is to have prototypes, is to be passed >floating-point arguments, and is to be called by old-style C, make its >arguments "double" - even if that means not giving them type "Coord". > Sgi has make a weak attempt to address this "standard" problem. There is a cc -float flag to stop default promotion to doubles in argument/parameter lists. Just seems not to work they way I hoped in spliced code... I am not finished testing this out, so if anyone has any more insight, I would like for you to speak up. My design goal is to mix a library of K & R 1 code with ANSI C, and when the K & R stuff is upgraded, not change my ANSI C code. I guess that there is no performance penalty for passing by value floats as doubles, but I am not certain of it. It is more bytes to push to the stack. Another suggested solution is to make ANSI headers for K & R 1 code. This is a slippery issue and I am not certain about a robust answer. At least the run time code really breaks when the problem arises ! (Only with floats). Cheers! dan. +-----------------------------------------------------------------------------+ | karron@nyu.edu (mail alias that will always find me) | | Dan Karron | | . . . . . . . . . . . . . . New York University Medical Center | | 560 First Avenue \ \ Pager <1> (212) 397 9330 | | New York, New York 10016 \**\ <2> 10896 <3> <your-number-here> | | (212) 340 5210 \**\__________________________________________ | | Please Note : Soon to move to dan@karron.med.nyu.edu 128.122.135.3 (Nov 1 )| +-----------------------------------------------------------------------------+
goss@SNOW-WHITE.MERIT-TECH.COM (Mike Goss) (11/19/90)
> Date: Sat, 17 Nov 90 10:57:39 EST > From: karron%karron.med.nyu.edu@cunyvm.cuny.edu > Subject: Re: Mixing ANSI and K & R 1 code. ... > > Sgi has make a weak attempt to address this "standard" problem. There is a > cc -float flag to stop default promotion to doubles in argument/parameter > lists. Just seems not to work they way I hoped in spliced code... > > I am not finished testing this out, so if anyone has any more insight, I > would like for you to speak up. ... The "-float" option on cc has never affected default promotion to double in function arguments. It only affects intermediate results in floating point calculations. The cc man page in IRIX 3.3.1 explicitly says this ("This option does not affect float function arguments, which are always promoted to double unless function prototypes are used."), but earlier versions (3.2) did not. ------------------------------ Mike Goss Merit Technology Inc. (214)733-7018 goss@snow-white.merit-tech.com Disclaimer: This offer void except where prohibited by law.
ciemo@bananapc.wpd.sgi.com (Dave Ciemiewicz) (11/19/90)
In article <9011171557.AA16135@karron.med.nyu.edu>, karron@KARRON.MED.NYU.EDU writes: |> >>Seems you can't have newstyle argument lists (ANSI) receiving parameters |> >>from old styles,non prototyped code. |> >> |> >>I first tried to write all my new stuff in ANSI code, but it would |> >>always get float (Coord) arguments wrong. |> > |> >... |> > |> |> Sgi has make a weak attempt to address this "standard" problem. There is a |> cc -float flag to stop default promotion to doubles in argument/parameter |> lists. Just seems not to work they way I hoped in spliced code... |> Mr. Karron, you are mistaken. From the cc(1) manual page: -float Cause the compiler to never promote expressions of type float to type double . This option does not affect float function arguments, which are always promoted to double unless function prototypes are used. As is explained, -float has nothing to do with C function prototypes. -float is useful for preventing K&R style float-to-double conversion in floating arithmetic operations. The following example illustrates the problem. float a, b, c; c = a * b; In K&R C, a and b, which are float are first both promoted to double, the a double precision multiply occurs, the result is converted to float and then assigned to c. When doing numerical computations with lots of data, the expense of all the floating point conversions between float and double may outweigh the benefit of the extra precision. This is especially true when doing dynamic 3D graphics where a fast qualitative result may be a higher priority than quantitative accuracy. Invoking -float prevents the unneeded and expensive promotion to double in the above example. The ANSI C standard permits float arithmetic instead of requiring double. |> I am not finished testing this out, so if anyone has any more insight, I |> would like for you to speak up. |> |> My design goal is to mix a library of K & R 1 code with ANSI C, and when the |> K & R stuff is upgraded, not change my ANSI C code. |> Another suggested |> solution is to make ANSI headers for K & R 1 code. This is a slippery issue |> and I am not certain about a robust answer. At least the run time code really |> breaks when the problem arises ! (Only with floats). |> Both you and the other gentlemen are probably falling into the following trap. This is not the result of a "weak attempt" on SGI's part to conform to standards but a problem inherent in trying to mix K&R C with ANSI C. If you have a library function coded as: float func(a, b) float a; float b; { . . . } you are using old style K&R C function declarations. If you provide a prototyped extern declaration, although it may be counter intuitive, you should declare the prototype as: extern float func(double, double); Why? Well in the presence of K&R style coding of the function, the C compiler must assume that you want K&R style float argument passing. That is, the call site must promote float arguments to double and then the called function must convert the double arguments back to float. This is most assuredly the case when working with precompiled libraries built without the use of function prototypes. The above extern function prototype is actually telling it like it is with K&R C style argument passing. |> I guess that there is no performance penalty for passing by value floats |> as doubles, but I am not certain of it. It is more bytes to push to the |> stack. Given the example above, do the call: float x, y, z; . . . z = func(x, y); There is more than just the penalty of pushing twice as many bytes around on the stack. There also is the penalty of promoting x and y to double and than back to float again inside func for a and b, as mentioned above. These conversions are extra cycles that are wasted. By doing the ANSI C prototype conversion: extern float func(float, float); float func(float a, float b) { . . . } You are doing more than getting type checking, you telling the compiler to be more efficient by eliminating 4 unnecessary type conversions, per function call, 2 at the call site and 2 inside the function. One last gotcha in this scenario is that once the function is implemented with the prototype form, all call sites must agree on the calling conventions. In this case, if you declare the function as: float func(float a, float b) { . . . } but call the function in an old K&R style module as: extern float func(); float x, y, z; z = func(x, y); /* Fails because compiler promotes unknowingly promotes x & y to double */ or without the benefit of an extern declaration, the call site will assume K&R style function calls and thus fail. The way to remedy this is to make sure you have the ANSI C prototype extern declarations in header files for all functions that you have changed to the ANSI C prototype convention. These files must be appropriately included in each module which calls the corresponding functions. I hope this helps with the understanding of the issues involved in mixing K&R C and ANSI C. --- Ciemo
davea@quasar.wpd.sgi.com (David B.Anderson) (11/20/90)
>Sgi has make a weak attempt to address this "standard" problem. There is a > cc -float flag to stop default promotion to doubles in argument/parameter >lists. Just seems not to work they way I hoped in spliced code... The 3.3 cc man page tries to make it clear that -float does *not* apply to arguments/parameters. Check the -float option on the cc man page. [ David B. Anderson Silicon Graphics (415)335-1548 davea@sgi.com ] [``What can go wrong?'' --Calvin to Hobbes]