mms00786@uxa.cso.uiuc.edu (09/11/89)
Ok, I have wasted an entire weekend, so I hope wasting a little bandwidth is ok. I am trying to write a medium model Windows program. I have certain functions that are in seperate modules (obj files), and I need to call one from the other. Here's what happens: a) if I declare something like void FAR fnPlotSegment (hWnd, fFromX, fToX) HWND hWnd; float fFromX; float fToX; {...} then I am unable to pass the float type arguments! Everything compiles, runs, etc. but if I try to print the float values passed in, they are always 0.0! b) if I declare something like void FAR PASCAL fnPlotSegment ... then windows crashes the first time I call it! As in, no warning, lets go back to the C prompt and destroy the contents of the cmos setup too! c) but the declaration void FAR fnPlotAnalog (hWnd, fFromX, fToX) HWND hWnd; double fFromX; double fToX; {....} works without a glitch! The only problem is that with this solution, I am unable to sleep, because the only way I can explain it is that I am getting lucky with the "double" declaration, and its going to crash on Tuesdays with a lunar eclipse when the Panda bear at the zoo get pneumonia. Can someone please explain what I am doing wrong, or why any of the above makes sense? I am using the medium model, but the small model has the same symptoms. I am also compiling using the same line options that Petzold uses in his sample make files. I am using MSC 5.0. I have scanned K&R and parts of the MSC manuals, but the only difference between float and double should be the precision. I am also having incredible problems trying to pass user defined types as arguments to functions - as in just can't do it. Please help before I flunk out of school. Thanks, Milan mms00786@uxa.cso.uiuc.edu .
bryant@flash.UUCP (Mike Bryant) (09/12/89)
In Microsoft C a formal parameter of type float is supposed to always be promoted to double (in the same way that char is pro- moted to int). See the discussion in section 7.2.3, Formal Param- eters, of the Language Reference section of the manual. It ap- pears that this must be broken based on the behavior you are see- ing. Section 5.6.4 states that actual parameters of type float are always promoted to double (which must be working). When using the pascal calling convention the callee pops the parameters from the stack (unlike C where the caller pops the stack). If you call a function with the wrong number of parame- ters or the wrong types then the stack is corrupted. Most of the time this causes a crash of some kind. In your case you are pass- ing two doubles and the function expects two floats. You discovered the solution to the bug on your own! -- Mike Bryant uunet.uu.net!amc!sigma!bryant Summation Inc. 11335 NE 122nd Way Kirkland, WA 98034
larry@csccat.UUCP (Larry Spence) (09/13/89)
In article <246400022@uxa.cso.uiuc.edu> mms00786@uxa.cso.uiuc.edu writes: >Here's what happens: > >a) if I declare something like > void FAR fnPlotSegment (hWnd, fFromX, fToX) > HWND hWnd; > float fFromX; > float fToX; > {...} > then I am unable to pass the float type arguments! Everything compiles, runs, > etc. but if I try to print the float values passed in, they are always 0.0! I believe that there is a documented bug in LINK4 (?) that screws up floats passed to functions. You'll have to either use pointers to floats, which you may have to make static, or doubles. The former is usually preferable. >I am also having incredible problems trying to pass user defined types as >arguments to functions - as in just can't do it. I used to have a lot of problems with this. For example, passing a param of type COMPLEX, where COMPLEX is a struct with the real and imaginary parts, caused all kinds of bizarre behavior. The best thing to do is to pass a pointer instead, since the code generated is pretty simple in that case. Note that the likelihood and severity of these problems varies slightly from 4.X to 5.X. Larry Spence larry@csccat ...{texbell,texsun,attctc}!csccat!larry "Fatal Exit Code 0x0001! Ack!"
kyler@pyr.gatech.EDU (J. Kyle Rogers) (09/13/89)
There was a note in one of the readme files included with MSC 5.1 about how floating point arguments to functions should all be double under ANSI C and, therefore, MSC 5.1 in order for everything to work correctly. The note explained the issue pretty well. Sorry' I don't have access to it at the moment, or I'd post it. ---krogers | krogers -- J. Kyle Rogers -- Technology Dynamics Inc. | | 145 15th Street N.E., Suite 624 -- Atlanta, GA 30361 | |uucp: ...!{akgua,allegra,amd,hplabs,ihnp4,seismo,ut-ngp}!gatech!gitpyr!kyler| |ARPA: kyler@pyr.gatech.edu |
mikek@ziebmef.mef.org (Mike King) (09/14/89)
In article <246400022@uxa.cso.uiuc.edu> mms00786@uxa.cso.uiuc.edu writes: >Here's what happens: > >a) if I declare something like > void FAR fnPlotSegment (hWnd, fFromX, fToX) > HWND hWnd; > float fFromX; > float fToX; > {...} > then I am unable to pass the float type arguments! Everything compiles, runs, > etc. but if I try to print the float values passed in, they are always 0.0! >c) but the declaration > void FAR fnPlotAnalog (hWnd, fFromX, fToX) > HWND hWnd; > double fFromX; > double fToX; > {....} > works without a glitch! The only problem is that with this solution, I am >Milan I've had the exact same problem with passing float arguments in Windows! And I got around it by using doubles instead of floats. I know people are thinking "Changing to doubles pushes the stack around and maskes the real bug", but I don't think so. This application works flawlessly in debug Windows. No problems anywhere else since I changed from floats to doubles?!?!? It's very suspicious and I welcome any explanation. For reference: we compile using the alternate math library.
rogerson@PEDEV.Columbia.NCR.COM (Dale Rogerson) (09/16/89)
People have been having problems with functions to which tthey have passed float types. They solved this problem by uses doubles instead of floats. Why does using doubles instead of floats work? Because in ANSI C (which MSC 5.1 is partly, somewhat, maybe, kinda, like ...) all float types are promoted to doubles!!! If you what to use floats and pass floats you must use function prototypes. Function prototypes stop the compiler from making these type of automaic promotions. I found this out by reading the book: ANSI C: A Lexical Guide Published by Mark Williams Company Prentice Hall ISBN 0-13-037814-3 I just checked it out from the library today. Learn something new everyday. -----Dale Rogerson-----
mms00786@uxa.cso.uiuc.edu (09/17/89)
Thanks to all who responded, by email, here, and otherwise. The problem is that the original K&R specified that all float arguments be promoted to double. To avoid this promotion, you need to have funtion prototypes. Furthermore, the prototypes have to be in the following format - In files that will be using the extern function, you need something like this - void far fnPlotSegment (int, float, float); In the module that contains the function, you must have - void FAR fnPlotSegment (int myVar1, float myVar2, float myVar3) {... } Note that the following will _not_ work - void FAR fnPlotSegment (myVar1, myVar2, myVar3) int myVar1; float myVar2; float myVar3; {... } Once again thank you for clarifying this point. Milan mms00786@uxa.cso.uiuc.edu .
pdavid@polyslo.CalPoly.EDU (Paul C. David) (09/19/89)
mikek@ziebmef.mef.org (Mike King) writes: >I've had the exact same problem with passing float arguments in Windows! >And I got around it by using doubles instead of floats. I know people are I was REALLY skeptical when I saw this the first time. But I stand corrected, some co-workers recall seeing something about passing floats in the bug list on ONLINE. Another good one is that you don't want to return doubles from a function, as this COULD foul up Global memory. So.... you need to pass the double as a pointer, or declare your function as FAR PASCAL. Have fun.... -Paul. -- Paul C. David pdavid@polyslo.CalPoly.EDU California Polytechic State University, San Luis Obispo Home of the six-year or 60,000 mile undergraduate degree