romwa@gpu.utcs.toronto.edu (Royal Ontario Museum) (01/18/89)
I am reposting this query because I didn't receive any replies to my original posting. Can someone help out? I am having some problems with using float's in functional prototypes and am hoping that someone out there in netland can help me out. The problem seems to be isolated to float types and not to any other types. The examples below give the gist of it. Tst2.c has a function "afunc" with one parameter. When I compile the two files, I get a warning that the type of the argument in the prototype doesn't match the declaration (??). I experimented with this example a bit on a couple of compilers and each time the warnings come out. What is more disconcerting is that flt_val inside afunc isn't 6.5 but some bizarre value. A couple of other observations are that by changing the type to be double made everything work, and by removing the prototypes made everything work. Since MS-C 5.1, QuickC, and Turbo C give similar results I assume it is something about C that I don't understand. advTHANKSance Totally Perplexed, Pavneet Arora ...!utgpu!rom!pavneet Royal Ontario Museum 100 Queen's Park Toronto, Ontario M5S 2C6 (416) 585-5626 ---------tst.c------------------------------------------------- #include <stdio.h> void afunc( float ); void main( void ) { float flt_val = 6.5; afunc( flt_val ); } ---------tst2.c------------------------------------------------ #include <stdio.h> void afunc( float ); void afunc( flt_val ) float flt_val; { int i; i = 3; }
Ralf.Brown@B.GP.CS.CMU.EDU (01/19/89)
In article <1989Jan18.092522.14499@gpu.utcs.toronto.edu>, romwa@gpu.utcs.toronto.edu (Royal Ontario Museum) writes: }I am having some problems with using float's in functional }prototypes ... }When I compile the two files, I get a warning that the type of }the argument in the prototype doesn't match the declaration }---------tst2.c------------------------------------------------ }#include <stdio.h> } }void afunc( float ); } }void afunc( flt_val ) } }float flt_val; } }{ } int i; } } i = 3; }} } The problem is that you are using an old-style declaration. In old-style declarations, parameters get widened according to specific rules. One of the rules is that floats get widened to double, so you are really declaring a function that takes a double parameter. That's why the compilers complain, and also why you get garbage for the parameter--it is taking the four bytes for the float plus an additional four bytes of garbage from the stack and trying to interpret that as a double. If you're going to use prototypes, you're pretty much going to have to use new-style declarations when defining functions. (i.e. void afunc(float flt_val) ) -- UUCP: {ucbvax,harvard}!cs.cmu.edu!ralf -=-=-=- Voice: (412) 268-3053 (school) ARPA: ralf@cs.cmu.edu BIT: ralf%cs.cmu.edu@CMUCCVMA FIDO: Ralf Brown 1:129/31 Disclaimer? I claimed something? You cannot achieve the impossible without attempting the absurd.
scjones@sdrc.UUCP (Larry Jones) (01/20/89)
In article <1989Jan18.092522.14499@gpu.utcs.toronto.edu>, romwa@gpu.utcs.toronto.edu (Royal Ontario Museum) writes: > When I compile the two files, I get a warning that the type of > the argument in the prototype doesn't match the declaration > > void afunc( float ); > > void afunc( flt_val ) > float flt_val; > { > int i; > > i = 3; > } The problem is that you have witten the function definition using the old-style syntax. When you do that, the function expects to be called with widened arguments (i.e. the float argument will actually be passed as a double). To fix the problem, either change the float in the prototype to double or write the definition using prototype form: void afunc( float flt_val ) { } ---- Larry Jones UUCP: uunet!sdrc!scjones SDRC scjones@sdrc.UU.NET 2000 Eastman Dr. BIX: ltl Milford, OH 45150 AT&T: (513) 576-2070 "When all else fails, read the directions."
erc@pai.UUCP (Eric Johnson) (01/20/89)
[...] In article <1989Jan18.092522.14499@gpu.utcs.toronto.edu>, romwa@gpu.utcs.toronto.edu (Royal Ontario Museum) writes: > I am having some problems with using float's in functional > prototypes and am hoping that someone out there in netland can > help me out. The problem seems to be isolated to float types > and not to any other types. The examples below give the gist > of it. Tst2.c has a function "afunc" with one parameter. > When I compile the two files, I get a warning that the type of > the argument in the prototype doesn't match the declaration > (??). I experimented with this example a bit on a couple > of compilers and each time the warnings come out. What is > more disconcerting is that flt_val inside afunc isn't 6.5 but > some bizarre value. > A couple of other observations are that by changing > the type to be double made everything work, and by removing > the prototypes made everything work. Since MS-C 5.1, QuickC, > and Turbo C give similar results I assume it is something > about C that I don't understand. > advTHANKSance > Totally Perplexed, > > Pavneet Arora > ...!utgpu!rom!pavneet > > Royal Ontario Museum > 100 Queen's Park > Toronto, Ontario > M5S 2C6 > (416) 585-5626 I, too, had problems using a float in a function prototype for MS C 5.1. I recently upgraded from 4.0 to 5.1 and code that worked in 4.0, using the float in a prototype, failed in 5.1. If I remember correctly, the 5.1 compiler gave a warning message for the prototype. The fix: I removed the prototype and everything was hunky-dory. The problem is that this defeats the whole idea of using prototypes in the first place. It is interesting that you state the problem appears in both Borland's and Microsoft's compilers (we were thinking of switching to Turbo C, I guess we won't now). If anyone has a code section using a float in a prototype that works under MS C 5.1, I would appreciate the example code. I may be doing something wrong and I certainly wouldn't mind a constructive correction. In my case, we used something like: (I may have typed this in wrong, so no flames, please) int foo( float /* f */, int /* i */, int /* j */ ); as the prototype and int foo( f, i, j ) float f; int i; int j; { /* ... */ } as the function. This seemed to cause great problems, as the float value f never seemed to have the correct value upon entry to the function. This is no fun. Again, removing the prototype seemed to solve the problem. Does anyone have any ideas? I would appreciate any, although dumping the PC and getting a real computer is not really an option, no matter how much I'd like to do that. Thanks, -Eric [ Pavneet Arora's examples of the problem follow ] > > ---------tst.c------------------------------------------------- > #include <stdio.h> > > void afunc( float ); > > void main( void ) > { > float flt_val = 6.5; > > afunc( flt_val ); > } > > > ---------tst2.c------------------------------------------------ > #include <stdio.h> > > void afunc( float ); > > void afunc( flt_val ) > > float flt_val; > > { > int i; > > i = 3; > } -- Eric F. Johnson | Phone +1 612-894-0313 | Are we Prime Automation,Inc | UUCP: bungia!pai!erc | having 12201 Wood Lake Drive | UUCP: sun!tundra!pai!erc | fun Burnsville, MN 55337 USA | DOMAIN: erc@pai.mn.org | yet?
gwyn@smoke.BRL.MIL (Doug Gwyn ) (01/21/89)
In article <365@pai.UUCP> erc@pai.UUCP (Eric Johnson) writes: >Does anyone have any ideas? Don't mix prototypes with old-style. In particular, use a prototype for the function definition also.
geoff@warwick.UUCP (Geoff Rimmer) (01/23/89)
In article <1989Jan18.092522.14499@gpu.utcs.toronto.edu> romwa@gpu.utcs.toronto.edu (Royal Ontario Museum) writes: >---------tst.c------------------------------------------------- > #include <stdio.h> > > void afunc( float ); > > void main( void ) > { > float flt_val = 6.5; > > afunc( flt_val ); > } > > >---------tst2.c------------------------------------------------ > #include <stdio.h> > > void afunc( float ); > > void afunc( flt_val ) > float flt_val; > > { > int i; > i = 3; > } The problem is that you are using the old way of defining the function afunc(). You should the new method: void afunc(float flt_val) { ... } BTW, rather than have to repeat the function prototype in both source files, put it once in tst2.h, and get both tst.c and tst2.c to #include "tst2.h". Finally, if you want to do a function prototype for a function with no arguments (e.g. main() in your example), the PROTOTYPE should have 'void' between the parentheses, but the DEFINITION shouldn't: e.g., rewriting your tst.c #include <stdio.h> void afunc(float); void main(void); /* prototype */ void main() /* definition */ { float flt_val = 6.5; afunc( flt_val ); } ------------------------------------------------------------ Geoff Rimmer, Computer Science, Warwick University, England. geoff@uk.ac.warwick.emerald "Why don't we go out for just ONE drink?" "No. Because you know what would happen then, don't you?" "Lager Frenzie!" "And one thing you can't do after Lager Frenzie, is get up at 4.30 in the morning." "We could exercise restraint." "Yes, but then again in the real world, perhaps we couldn't!" - Filthy Rich and Catflap, 1986. ------------------------------------------------------------
jbs@fenchurch.mit.edu (Jeff Siegal) (01/24/89)
In article <23d5d581@ralf> Ralf.Brown@B.GP.CS.CMU.EDU writes: >If you're going to use prototypes, you're pretty much going to have to use >new-style declarations when defining functions. I don't see any reason that this is true. You just need to know about the promotion rules. If you mix prototypes and old-style definitions, you can get code which compiles on both old and new C compilers (assuming you use some sort of conditional compilation to turn the prototypes into old-style declarations). You still get most of the advantages of prototypes. Jeff Siegal
karl@haddock.ima.isc.com (Karl Heuer) (01/27/89)
In article <942@ubu.warwick.UUCP> geoff@emerald.UUCP (Geoff Rimmer) writes: >... Finally, if you want to do a function prototype for a function with no >arguments (e.g. main() in your example), the PROTOTYPE should have 'void' >between the parentheses, but the DEFINITION shouldn't: I see no reason to make such an exception. If you've got prototypes, use them for both declarations and defintions, whether or not the function takes a positive number of arguments. In particular, int main(void) { return 0; } is perfectly correct. The old style (without `void') is obsolescent. Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
geoff@warwick.UUCP (Geoff Rimmer) (02/01/89)
In article <11556@haddock.ima.isc.com> karl@haddock.ima.isc.com (Karl Heuer) writes: >In article <942@ubu.warwick.UUCP> geoff@emerald.UUCP (Geoff Rimmer) writes: >>... Finally, if you want to do a function prototype for a function with no >>arguments (e.g. main() in your example), the PROTOTYPE should have 'void' >>between the parentheses, but the DEFINITION shouldn't: > >I see no reason to make such an exception. If you've got prototypes, use >them for both declarations and defintions, whether or not the function takes a >positive number of arguments. In particular, > int main(void) { return 0; } >is perfectly correct. The old style (without `void') is obsolescent. Well I don't know what the dpANS says about this, but I had problems with QuickC not recognising that I had declared (prototyped) several functions. Eventually, I realised this behaviour was only happening on functions with no params, then by changing for example int main(void) { ... } to int main() { ... } it worked fine. Maybe its a bug in QuickC, but I've seen examples of writing prototyped functions, and in every case the prototype takes void, and the definition takes empty parentheses. >Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint Geoff ------------------------------------------------------------ Geoff Rimmer, Computer Science, Warwick University, England. geoff@uk.ac.warwick.emerald "Came in? ... Isn't this where we" - Pink Floyd, The Wall ------------------------------------------------------------
guy@auspex.UUCP (Guy Harris) (02/04/89)
>>I see no reason to make such an exception. If you've got prototypes, use >>them for both declarations and defintions, whether or not the function takes a >>positive number of arguments. In particular, >> int main(void) { return 0; } >>is perfectly correct. The old style (without `void') is obsolescent. > >Well I don't know what the dpANS says about this,... The dpANS most definitely says that int foo(void) { return 0; } is perfectly correct. It doesn't come right out and say that the old style (without `void') is obsolescent; however, the May 13, 1988 draft says that an implementation may generate a warning if "a function is called but no prototype has been specified". This sounds to me as if they don't think that old-style definitions are the Right Way To Go; it sounds as if they think they're kept around for backwards compatibility and should not be used in new code. >Maybe its a bug in QuickC, It most definitely *is* a bug in QuickC if it can't cope with int foo(void) { ... } and it purports to match some draft of the pANS. If it doesn't purport to match any draft of the pANS, it's simply a horrible misfeature.