gore@eecs.nwu.edu (Jacob Gore) (04/25/89)
Is this valid ANSI C (or dpANS or whatever you want to call it):
void f(char);
void f(c)
char c;
{
}
The version of GNU cc I have complains:
t.c: In function f:
t.c:5: argument `c' doesn't match function prototype
t.c:5: a formal parameter type that promotes to `int'
t.c:5: can match only `int' in the prototype
Is this rule for real, or is this just a gcc bug?
Jacob Gore Gore@EECS.NWU.Edu
Northwestern Univ., EECS Dept. {oddjob,chinet,att}!nucsrl!gore
schmidt@zola.ics.uci.edu (Doug Schmidt) (04/27/89)
In article <3950014@eecs.nwu.edu> gore@eecs.nwu.edu (Jacob Gore) writes: ++ Is this valid ANSI C (or dpANS or whatever you want to call it): ++ ++ void f(char); ++ ++ void f(c) ++ char c; ++ { ++ } ++ ++ The version of GNU cc I have complains: ++ ++ t.c: In function f: ++ t.c:5: argument `c' doesn't match function prototype ++ t.c:5: a formal parameter type that promotes to `int' ++ t.c:5: can match only `int' in the prototype ++ ++ Is this rule for real, or is this just a gcc bug? This is a real rule. Read the GNU C documentation: ---------------------------------------- Users often think it is a bug when GNU CC reports an error for code like this: int foo (short); int foo (x) short x; { } The error message is correct: this code really is erroneous, because the old-style non-prototype definition passes subword integers in their promoted types. In other words, the argument is really an int, not a short. The correct prototype is this: int foo (int); ---------------------------------------- Doug -- On a clear day, under blue skies, there is no need to seek. And asking about Buddha +------------------------+ Is like proclaiming innocence, | schmidt@ics.uci.edu | With loot in your pocket. | office: (714) 856-4043 |
gwyn@smoke.BRL.MIL (Doug Gwyn) (04/27/89)
In article <3950014@eecs.nwu.edu> gore@eecs.nwu.edu (Jacob Gore) writes: > void f(char); > void f(c) > char c; > { > } >The version of GNU cc I have complains: Once again GCC is correct. The "old style" function definition is of a function that is passed an int (NOT a char) argument when it is called and which subsequently accesses the least-significant char of the int that was passed. The prototype declaration is for a function that is (potentially) passed just a char, not an int. Therefore the argument- passing details are potentially different between the two cases, and it is considered a function declaration/definition mismatch.
ark@alice.UUCP (Andrew Koenig) (04/27/89)
In article <3950014@eecs.nwu.edu>, gore@eecs.nwu.edu (Jacob Gore) writes: > Is this valid ANSI C (or dpANS or whatever you want to call it): > > void f(char); > > void f(c) > char c; > { > } No. When you say void f(c) char c; { /* stuff */ } that is essentially equivalent to: void f(int c_temp) { char c = c_temp; { /* stuff */ } } Neither is equivalent to void f(char c) { /* stuff */ } See page 60 of `C Traps and Pitfalls.' -- --Andrew Koenig ark@europa.att.com
kremer@cs.odu.edu (Lloyd Kremer) (04/27/89)
In article <3950014@eecs.nwu.edu> gore@eecs.nwu.edu (Jacob Gore) writes: >Is this valid ANSI C (or dpANS or whatever you want to call it): > > void f(char); > > void f(c) > char c; > { > } > >The version of GNU cc I have complains: > > t.c: In function f: > t.c:5: argument `c' doesn't match function prototype > t.c:5: a formal parameter type that promotes to `int' > t.c:5: can match only `int' in the prototype The responses I have seen all make reference to "old style" automatic widening of the function argument to an int. The fact that the original poster specified ANSI C suggests that he knows about the "old style" rules. In any case I know I do. :-) But I thought that in the new ANSI C (not old-- NEW!) you could effectively circumvent this behavior and request that small types be received by the called function as a true char (or float, or whatever), size and all. There may still be temporary internal promotion due to hardware characteristics such as the inability to push a single byte onto the stack, but this should be transparent to the programmer. So, I shall now ask: How do you tell the compiler that you want this *NEW* behavior? If a full prototype isn't good enough, what is? -- Lloyd Kremer Brooks Financial Systems ...!uunet!xanth!brooks!lloyd Have terminal...will hack!
gwyn@smoke.BRL.MIL (Doug Gwyn) (04/28/89)
In article <8661@xanth.cs.odu.edu> kremer@cs.odu.edu (Lloyd Kremer) writes: >So, I shall now ask: How do you tell the compiler that you want this *NEW* >behavior? If a full prototype isn't good enough, what is? You have to use the prototype form in the function definition as well.
karl@haddock.ima.isc.com (Karl Heuer) (04/28/89)
In article <8661@xanth.cs.odu.edu> kremer@cs.odu.edu (Lloyd Kremer) writes: >In article <3950014@eecs.nwu.edu> gore@eecs.nwu.edu (Jacob Gore) writes: >>[gcc complains about] >> void f(char); >> void f(c) char c; {...} >The responses I have seen all make reference to "old style" automatic widening >... How do you tell the compiler that you want this *NEW* behavior? If a >full prototype isn't good enough, what is? Specify a prototype on the *definition* as well as the declaration. Thus: extern void f(char); void f(char c) {...} Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
scs@adam.pika.mit.edu (Steve Summit) (04/29/89)
In article <3950014@eecs.nwu.edu> gore@eecs.nwu.edu (Jacob Gore) writes: >Is this valid ANSI C (or dpANS or whatever you want to call it): > void f(char); > void f(c) > char c; > {} > >The version of GNU cc I have complains: > t.c:5: argument `c' doesn't match function prototype > t.c:5: a formal parameter type that promotes to `int' > t.c:5: can match only `int' in the prototype >Is this rule for real, or is this just a gcc bug? Poor GNU! They get asked this ALL THE TIME, they put in a three line warning/explanation message, and people still don't get the idea. To recap, either use void f(int); void f(char); or void f(c) void f(char c) char c; {} {} The only difference is that the second form may allow the argument not to be widened when passed, for those architectures which support passing sub-word sized arguments. (In either case, c will act like a char within function f, being narrowed if necessary, and having its effective address adjusted so that something like f(c) char c; { write(1, &c, 1); } works correctly on big-endian architectures. Don't write that, though; write(,,1) brings a machine to its knees.) Steve Summit scs@adam.pika.mit.edu
guy@auspex.auspex.com (Guy Harris) (05/02/89)
>In any case I know I do. :-) But I thought that in the new ANSI C (not old-- >NEW!) you could effectively circumvent this behavior and request that small >types be received by the called function as a true char (or float, or >whatever), size and all. You can. >So, I shall now ask: How do you tell the compiler that you want this *NEW* >behavior? If a full prototype isn't good enough, what is? A full prototype *is* good enough. The problem is that the code given in the example doesn't have a full prototype *definition* of the function; you have to define it as: void f(char c) { ... }