steve@cpoint.UUCP (Stephen Steir) (04/11/90)
I post this example in hopes that it will save time for other Manx 5.0a users. Compile the following program with large code and data -mcd. int foo(a, b, c) short a, b, c; { printf("a = %d b = %d c = %d\n", a, b, c); } main() { int (*p2foo)(); short a, b, c; a = 1; b = 2; c = 3; p2foo = foo; (*p2foo)(a, b, c); } You will notice that a, b and c get pushed on the stack incorrectly as longs yet foo will still unwrap a, b, and c correctly as shorts. When run, foo prints a = 1 b = 0 c = 2. This bug has been reported and Manx says that it will be fixed in the next release. ------------------------------------------------------------------------------ Steve Steir - Clearpoint Research Corp., 35 Parkwood Dr., Hopkinton, Ma. 01748 UUCP: steve@frog!cpoint ATT: (508) 435-2000 BIX: clearpoint ------------------------------------------------------------------------------
new@udel.EDU (Darren New) (04/12/90)
In article <4606@cpoint.UUCP> steve@cpoint.UUCP (Stephen Steir) writes: >I post this example in hopes that it will save time for other Manx 5.0a users. > int (*p2foo)(); Maybe you should try int (*p2foo)(short, short, short); This works for me in LC5.04 and I get warnings if I don't put the arguments in. I suspect this is not really a bug. -- Darren
amr@dukee.egr.duke.edu (Anthony M. Richardson) (04/12/90)
From article <16544@estelle.udel.EDU>, by new@udel.EDU (Darren New): > In article <4606@cpoint.UUCP> steve@cpoint.UUCP (Stephen Steir) writes: >>I post this example in hopes that it will save time for other Manx 5.0a users. >> int (*p2foo)(); > Maybe you should try int (*p2foo)(short, short, short); > This works for me in LC5.04 and I get warnings if I don't put the > arguments in. I suspect this is not really a bug. -- Darren I agree, I don't think it is a bug either. Since (*p2foo) is not prototyped how can the compiler possibly know how to cast the arguments? And, since in the original post, (*p2foo) was not prototyped, I think the compiler correctly cast its arguments as longs.
steve@cpoint.UUCP (Stephen Steir) (04/13/90)
In article <738@cameron.cs.duke.edu> amr@dukee.egr.duke.edu (Anthony M. Richardson) writes: >From article <16544@estelle.udel.EDU>, by new@udel.EDU (Darren New): >> In article <4606@cpoint.UUCP> steve@cpoint.UUCP (Stephen Steir) writes: >>>I post this example in hopes that it will save time for other Manx 5.0a users. >>> int (*p2foo)(); >> Maybe you should try int (*p2foo)(short, short, short); >> This works for me in LC5.04 and I get warnings if I don't put the >> arguments in. I suspect this is not really a bug. -- Darren > >I agree, I don't think it is a bug either. Since (*p2foo) is not >prototyped how can the compiler possibly know how to cast the >arguments? And, since in the original post, (*p2foo) was not >prototyped, I think the compiler correctly cast its arguments as longs. It is impossible to predict an argument prototype for a pointer to a function. 'C' compilers have always pushed a short argument as a short and the only advantage of a function prototype is to warn the programer of mismatched types. If shorts get pushed as longs, how would you expect printf to work? Further, how would you prototype printf? The example doesn't show it, but I did try casting the arguments to shorts before they were pushed which also didn't work. ------------------------------------------------------------------------------ Steve Steir - Clearpoint Research Corp., 35 Parkwood Dr., Hopkinton, Ma. 01748 UUCP: steve@frog!cpoint ATT: (508) 435-2000 BIX: clearpoint ------------------------------------------------------------------------------
new@udel.EDU (Darren New) (04/13/90)
In article <4631@cpoint.UUCP> steve@cpoint.UUCP (Stephen Steir) writes: >It is impossible to predict an argument prototype for a pointer to a >function. Not true. It was just done in the previous post of this thread. The human can always predict what arguments to pass; how else would he or she know what to code as arguments? >'C' compilers have always pushed a short argument as a short No again. C compilers have always pushed shorts as ints. Only if short==int is that true. >and the only advantage of a function prototype is to warn the programer >of mismatched types. Bzzzt. Three strikes! The prototype is also used to cast constants to the correct size (I think) and cast vars/expressions to the correct size after a warning. Or something like that. -- Darren
rchampe@hubcap.clemson.edu (Richard Champeaux) (04/13/90)
In article <4631@cpoint.UUCP> steve@cpoint.UUCP (Stephen Steir) writes: >In article <738@cameron.cs.duke.edu> amr@dukee.egr.duke.edu (Anthony M. Richardson) writes: >>From article <16544@estelle.udel.EDU>, by new@udel.EDU (Darren New): >>> In article <4606@cpoint.UUCP> steve@cpoint.UUCP (Stephen Steir) writes: > >It is impossible to predict an argument prototype for a pointer to a >function. 'C' compilers have always pushed a short argument as a short >and the only advantage of a function prototype is to warn the programer >of mismatched types. If shorts get pushed as longs, how would you expect >printf to work? Further, how would you prototype printf? > >The example doesn't show it, but I did try casting the arguments to shorts >before they were pushed which also didn't work. > Almost. Non-ansi C casts chars and shorts as ints when passing them as arguments or when using them in expressions. Pre 5.0 versions of Aztec, unless told otherwise with "+L", defined ints to be the same size as shorts. Therefore, shorts were passed as shorts, since they were the same size as ints. Version 5.0, however, defines the default int size as long. Therefore, shorts are converted to ints (longs) before they are passed as parameters or used in equations. Even if you cast something as a short when you pass it in a function call, it will be cast into an int before it is pushed onto the stack. (at least this is the case with non-ansi C) This is why you can use the format character "%d" in a printf() with chars, shorts, and ints. I don't really know anything about ANSI C, but it would seem that it assumes that integer parameters are to be cast as ints unless there is a prototype for that function. In the example that was posted, the actual function was prototyped, but the function pointer definition had no prototype. Since the compiler can have no knowledge of what type of parameters will be used by the function pointed to by the pointer, without a prototype, then it must assume that the arguments are to be cast as ints before they are pushed onto the stack. Remember, ints in 5.0 are the same size as longs. There is therefore nothing wrong with the compilers interpretation of that program. That was an example of a programming error, not a compiling error. BTW, in expressions and parameter passing, floats are cast as doubles. This would say that if your math library has different variable sizes for floats and doubles, then you might as well use doubles everywhere, since it will cast the floats into doubles before it uses them and then cast the result back into a float before it stores the result. You don't save any computation time when using floats, you actually increase the time, since you force the compiler to do a conversion evertime it accesses the variable, and then you just throw away the extra precision when it stores the result. I believe, however, that the Motorola FFP library (the default) uses 32 bits for both floats and doubles, so no conversion would take place. The IEEE double precision library, however, probably has different variable sizes for floats and doubles. >Steve Steir - Clearpoint Research Corp., 35 Parkwood Dr., Hopkinton, Ma. 01748 ------------------------------------------------------------------------------ Rich Champeaux PLT: The plotter device for the Amiga! rchampe@hubcap.clemson.edu Ask for it at your neighborhood FTP site! "It's never too late to do nothing at all." ------------------------------------------------------------------------------