468,746 Members | 1,831 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,746 developers. It's quick & easy.

gcc prototype oddity

Thomas Heinz wrote (in re. gcc compilation of this erroneous
program):

$ cat test.c
int f(int);
int f();
int f() {return 0;}

int main (void) { return 0; }
The only point which remains concerns the error statement for
the program ... which is:

test.c: In function f:
test.c:3: error: number of arguments doesn't match prototype
test.c:2: error: prototype declaration

Here, it would be nice if the prototype declaration (3rd line of
error statement) refers to the strictest declaration (in the
example line 1).


Interesting: that message does seem wrong, since there's no
inconsistency between lines 2 and 3, only between 1 and 3.

I'm cc'ing comp.lang.c.

Allin Cottrell.
Nov 14 '05 #1
23 2191
Allin Cottrell wrote:
Thomas Heinz wrote:

$ cat test.c
1 int f(int);
2 int f();
3 int f() { return 0; }
4
5 int main(void) { return 0; }
The only point which remains concerns the error statement for
the program ... which is:

test.c: In function f:
test.c:3: error: number of arguments doesn't match prototype
test.c:2: error: prototype declaration

Here, it would be nice if the prototype declaration
(3rd line of error statement) refers to
the strictest declaration (in the example line 1).
Interesting: that message does seem wrong,
since there's no inconsistency
between lines 2 and 3, only between 1 and 3.


No, the message is correct.
The declaration

int f();

is a redeclaration of

int f(int);

and far as the compiler can tell.
cat main.c int f();
int f(int);
int f() { return 0; }

int main(void) { return 0; }
gcc -Wall -std=c99 -pedantic -o main main.c

main.c: In function `f':
main.c:3: error: number of arguments doesn't match prototype
main.c:2: error: prototype declaration

The compiler is *not* clairvoyant.
It does not know any more than I do what you *intended* to write.

Since the type specifier appears in the declaration

int f(int);

the mistake may be that the declaration

int f(void);

was intended where you wrote

int f();

in which case you should also have written

int f(void) { return 0; }
Nov 14 '05 #2
Allin Cottrell wrote:
Thomas Heinz wrote (in re. gcc compilation of this erroneous
program):

$ cat test.c
int f(int);
int f();
int f() {return 0;}

int main (void) { return 0; }
The only point which remains concerns the error statement for
the program ... which is:

test.c: In function f:
test.c:3: error: number of arguments doesn't match prototype
test.c:2: error: prototype declaration

Here, it would be nice if the prototype declaration (3rd line of
error statement) refers to the strictest declaration (in the
example line 1).

Interesting: that message does seem wrong, since there's no
inconsistency between lines 2 and 3, only between 1 and 3.

I'm cc'ing comp.lang.c.

Allin Cottrell.


The compiler's error messages are correct.

Line 1 is ok - it defines the prototype for f().

Line 2 is an error - it attempts to redefine the prototype
for f() that was already defined by line 1.

Line 3 is an error - it does not match the prototype for
f() that was defined by line 1.

In 'C' there can only be one prototype for a given
function name. The first one encountered in the
compilation is used (by most compilers).

Now if it was a C++ program you could have multiple
overloaded functions of the same name - each with
a different arg list.

Larry

--
Anti-spam address, change each 'X' to '.' to reply directly.
Nov 14 '05 #3
"Larry I Smith" <la***********@verizon.net> wrote in message
news:O_*******************@nwrddc01.gnilink.net...
Allin Cottrell wrote:
Thomas Heinz wrote (in re. gcc compilation of this erroneous
program):

$ cat test.c
int f(int);
int f();
int f() {return 0;}

int main (void) { return 0; }
.... The compiler's error messages are correct.

Line 1 is ok - it defines the prototype for f().

Line 2 is an error - it attempts to redefine the prototype
for f() that was already defined by line 1.

Line 3 is an error - it does not match the prototype for
f() that was defined by line 1.

In 'C' there can only be one prototype for a given
function name. The first one encountered in the
compilation is used (by most compilers).


Isn't line 2 a definition sans prototype? This appears to be benign.

Interestingly, if you reverse lines 1 and 2, you get the exact same errors
(and line numbers). gcc is apparently accepting both definitions, and the
error on line 3 just refers to the last definition, not the one to which
it's actually comparing the prototype.

S

--
Stephen Sprunk "Those people who think they know everything
CCIE #3723 are a great annoyance to those of us who do."
K5SSS --Isaac Asimov

Nov 14 '05 #4
Allin Cottrell wrote:
Thomas Heinz wrote (in re. gcc compilation of this erroneous
program):

$ cat test.c
int f(int);
int f();
int f() {return 0;}

int main (void) { return 0; }
The only point which remains concerns the error statement for
the program ... which is:

test.c: In function f:
test.c:3: error: number of arguments doesn't match prototype
test.c:2: error: prototype declaration

Here, it would be nice if the prototype declaration (3rd line of
error statement) refers to the strictest declaration (in the
example line 1).

Interesting: that message does seem wrong, since there's no
inconsistency between lines 2 and 3, only between 1 and 3.

I'm cc'ing comp.lang.c.

Allin Cottrell.


Here's my take, FWIW.

Line 1 declares a function f() returning int and taking one parameter of
type int.

Line 2 declares a function f(). It is not a prototype (I think Larry
Smith is wrong on this issue). Since the return types are the same, the
declarations are compatible. Notice if you change the return type to
float, you get an error.

Line 3 declares a function f(). This declaration is not a prototype, so
no problem. Line 3 also defines a function int f(void). The definition
does not match the prototype in line 1, and hence the error.

Notice you can do weird stuff with this declaration/definition disconnect.

void foo() {
foo(5);
foo(3.5);
foo("hello");
}

should compile as C, even though it's obviously illegal. But change it to

void foo() {
void foo(int);
}

and you'll get an error.

--
Pull out a splinter to reply.
Nov 14 '05 #5

On Tue, 22 Jun 2004, Allin Cottrell wrote:

Thomas Heinz wrote (in re. gcc compilation of this erroneous
program):

$ cat test.c
int f(int);
int f();
int f() {return 0;}

int main (void) { return 0; }
The only point which remains concerns the error statement for
the program ... which is:

test.c: In function f:
test.c:3: error: number of arguments doesn't match prototype
test.c:2: error: prototype declaration

Here, it would be nice if the prototype declaration (3rd line of
error statement) refers to the strictest declaration (in the
example line 1).


Interesting: that message does seem wrong, since there's no
inconsistency between lines 2 and 3, only between 1 and 3.

I'm cc'ing comp.lang.c.


Come not to clc for counsel, for they will say both "duuuh, what?"
and "that's off-topic."

Larry Smith's answer is wrong, though at least partially correct
for The Language That C Is Not. Tisdale's answer is flat wrong,
perhaps due to a misreading of the original program. Peter Ammon's
answer to your question is correct AFAICT (but I'm curious about
the 'void foo()' examples at the end of his post... chapter and
verse, Peter?).

1 int f(int);
2 int f();
3 int f() {return 0;}

As far as the Standard is concerned, and AFAICT, line 2 is fine
(it's just a redeclaration of the already-prototyped function).
Line 3 is invalid (conflicts with previous prototype), and thus
requires a diagnostic. GCC provides a diagnostic. Thus GCC is
perfectly conforming in this regard.

Now certainly GCC's diagnostic is not the most user-friendly; it
ought to point the programmer to the two lines which are in conflict,
rather than to the two most recent declarations of 'f'. I don't know
the internals of GCC, but it certainly *seems* like a ten-line fix
at most. ;) I would consider this a minor bug in GCC, deserving of
a bug report. I don't think comp.lang.c really needed to be dragged
into it. :)

-Arthur
Nov 14 '05 #6
Peter Ammon wrote:
Allin Cottrell wrote:
Thomas Heinz wrote (in re. gcc compilation of this erroneous
program):

$ cat test.c
int f(int);
int f();
int f() {return 0;}

int main (void) { return 0; }
The only point which remains concerns the error statement for
the program ... which is:

test.c: In function f:
test.c:3: error: number of arguments doesn't match prototype
test.c:2: error: prototype declaration

Here, it would be nice if the prototype declaration (3rd line of
error statement) refers to the strictest declaration (in the
example line 1).
Interesting: that message does seem wrong, since there's no
inconsistency between lines 2 and 3, only between 1 and 3.

I'm cc'ing comp.lang.c.

Allin Cottrell.

Here's my take, FWIW.

Line 1 declares a function f() returning int and taking one parameter of
type int.

Line 2 declares a function f(). It is not a prototype (I think Larry
Smith is wrong on this issue). Since the return types are the same, the
declarations are compatible. Notice if you change the return type to
float, you get an error.


Agreed.
Line 3 declares a function f(). This declaration is not a prototype, so
no problem. Line 3 also defines a function int f(void). The definition
does not match the prototype in line 1, and hence the error.


Again, agreed. The issue raised by Thomas is just this: the
disagreement is between the prototype on line 1 and the function
definition on line 3, yet the gcc error message refers to a
"prototype" on line 2.

--
Allin Cottrell
Department of Economics
Wake Forest University, NC
Nov 14 '05 #7
In <cb***********@f1n1.spenet.wfu.edu> Allin Cottrell <co******@wfu.edu> writes:
Thomas Heinz wrote (in re. gcc compilation of this erroneous
program):

$ cat test.c
int f(int);
int f();
int f() {return 0;}

int main (void) { return 0; }
The only point which remains concerns the error statement for
the program ... which is:

test.c: In function f:
test.c:3: error: number of arguments doesn't match prototype
test.c:2: error: prototype declaration

Here, it would be nice if the prototype declaration (3rd line of
error statement) refers to the strictest declaration (in the
example line 1).


Interesting: that message does seem wrong, since there's no
inconsistency between lines 2 and 3, only between 1 and 3.


The message about line 2 *is* wrong. Note, however, that, if I fix line 3
the message about line 2 goes away:

fangorn:~/tmp 48> cat test.c
int f(int);
int f();
int f(int i) {return 0;}
fangorn:~/tmp 49> gcc -c test.c
fangorn:~/tmp 50>

So, we have no conformance issue: the original code *required* at least
one diagnostic and got it. The correct code was correctly translated.

As for why the message about line 2 is wrong, here is the chapter and
verse from the C standard:

15 For two function types to be compatible, both shall specify
compatible return types. Moreover, the parameter type lists,
if both are present, shall agree in the number of parameters and
in use of the ellipsis terminator; corresponding parameters shall
have compatible types. If one type has a parameter type list
and the other type is specified by a function declarator that
is not part of a function definition and that contains an empty
identifier list, the parameter list shall not have an ellipsis
terminator and the type of each parameter shall be compatible
with the type that results from the application of the default
argument promotions...

Which means that

int f(int);
int f();

is OK, but

int f(float);
int f();

is not.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #8
Dan Pop wrote:
In <cb***********@f1n1.spenet.wfu.edu> Allin Cottrell <co******@wfu.edu> writes:

Thomas Heinz wrote (in re. gcc compilation of this erroneous
program):

$ cat test.c
int f(int);
int f();
int f() {return 0;}

int main (void) { return 0; }

The only point which remains concerns the error statement for
the program ... which is:

test.c: In function f:
test.c:3: error: number of arguments doesn't match prototype
test.c:2: error: prototype declaration

Here, it would be nice if the prototype declaration (3rd line of
error statement) refers to the strictest declaration (in the
example line 1).
Interesting: that message does seem wrong, since there's no
inconsistency between lines 2 and 3, only between 1 and 3.


The message about line 2 *is* wrong. Note, however, that, if I fix line 3
the message about line 2 goes away:

fangorn:~/tmp 48> cat test.c
int f(int);
int f();
int f(int i) {return 0;}
fangorn:~/tmp 49> gcc -c test.c
fangorn:~/tmp 50>


Fine, I don't find that surprising.
So, we have no conformance issue: the original code *required* at least
one diagnostic and got it. The correct code was correctly translated.


I guess my question is, where do conformance issues end and QoI issues
begin? You say, "the original code *required* at least one diagnostic
and got it". True, but what if the diagnostic had been:

test.c:666: error: elephants are trampling your begonias

The point that Thomas Heinz observed is that

test.c:2: error: prototype declaration

is not much better (though I accept the first diagnostic line given
by gcc was perfectly correct).

Allin Cottrell
Nov 14 '05 #9
On Wed, 23 Jun 2004 19:40:42 -0400, Allin Cottrell <co******@wfu.edu>
wrote:
Thomas Heinz wrote (in re. gcc compilation of this erroneous
program):

$ cat test.c
int f(int);
int f();
int f() {return 0;}
I guess my question is, where do conformance issues end and QoI issues
begin? You say, "the original code *required* at least one diagnostic
and got it". True, but what if the diagnostic had been:


This is a simple case of one correct error message followed by an
incorrect message.

I find that compilers do that quite often. Not something to
be unduly concerned about.

Nick.

Nov 14 '05 #10
Allin Cottrell wrote:
Peter Ammon wrote:
Allin Cottrell wrote:
Thomas Heinz wrote:

$ nl test.c
1 int f(int);
2 int f();
3 int f() { return 0; }
4
5 int main (void) { return 0; }

The only point which remains concerns the error statement for
the program ... which is:

test.c: In function f:
test.c:3: error: number of arguments doesn't match prototype
test.c:2: error: prototype declaration

Here, it would be nice if the prototype declaration (3rd line of
error statement) refers to the strictest declaration (in the
example line 1).


Interesting: that message does seem wrong, since there's no
inconsistency between lines 2 and 3, only between 1 and 3.

I'm cc'ing comp.lang.c.

Allin Cottrell.


Here's my take, FWIW.

Line 1 declares a function f() returning int and taking one parameter
of type int.

Line 2 declares a function f(). It is not a prototype (I think Larry
Smith is wrong on this issue). Since the return types are the same,
the declarations are compatible. Notice if you change the return type
to float, you get an error.

Agreed.
Line 3 declares a function f().
This declaration is not a prototype, so no problem.
Line 3 also defines a function int f(void). The
definition does not match the prototype in line 1, and hence the error.

Again, agreed. The issue raised by Thomas is just this:
the disagreement is between the prototype on line 1
and the function definition on line 3,
yet the gcc error message refers to a "prototype" on line 2.


You are thinking about this all wrong.
The declaration on line #2

int f();

is a re-declaration of the declaration on line #1

int f(int);

The definition on line #3

int f(void) { return 0; }

conflicts with *both* of the previous declarations.
The compiler cannot read the programmer's mind.
It *cannot* know the programmer's intent.

Nov 14 '05 #11
Dan Pop wrote:
In <cb***********@f1n1.spenet.wfu.edu> Allin Cottrell <co******@wfu.edu> writes:

Thomas Heinz wrote (in re. gcc compilation of this erroneous
program):

$ cat test.c
int f(int);
int f();
int f() {return 0;}

int main (void) { return 0; }

The only point which remains concerns the error statement for
the program ... which is:

test.c: In function f:
test.c:3: error: number of arguments doesn't match prototype
test.c:2: error: prototype declaration

Here, it would be nice if the prototype declaration (3rd line of
error statement) refers to the strictest declaration (in the
example line 1).


Interesting: that message does seem wrong, since there's no
inconsistency between lines 2 and 3, only between 1 and 3.

The message about line 2 *is* wrong. Note, however, that, if I fix line 3
the message about line 2 goes away:

fangorn:~/tmp 48> cat test.c
int f(int);
int f();
int f(int i) {return 0;}
fangorn:~/tmp 49> gcc -c test.c
fangorn:~/tmp 50>

So, we have no conformance issue: the original code *required* at least
one diagnostic and got it. The correct code was correctly translated.

As for why the message about line 2 is wrong, here is the chapter and
verse from the C standard:

15 For two function types to be compatible, both shall specify
compatible return types. Moreover, the parameter type lists,
if both are present, shall agree in the number of parameters and
in use of the ellipsis terminator; corresponding parameters shall
have compatible types. If one type has a parameter type list
and the other type is specified by a function declarator that
is not part of a function definition and that contains an empty
identifier list, the parameter list shall not have an ellipsis
terminator and the type of each parameter shall be compatible
with the type that results from the application of the default
argument promotions...

Which means that

int f(int);
int f();

is OK, but

int f(float);
int f();

is not.

Dan


Well, ok Dan, you are correct.

But in my defense, I was taught that this was
a bad programming practice (2 conflicting prototypes
for the same function).

The GNU WEB site states that once the C99 spec is
fully supported by GCC that it (C99) will become the
default mode for GCC. Once that is done, the
'int promotion' assumption will no longer be
supported and f() will no longer be assumed to
be the same as f(int). Per the CGG 'checklist'
of C99 conformance, some of this has already been
done. So, what we may be seeing here is partial
implementation of the C99 spec in the error handling
code. This is also mentioned in 6.11.6 and 6.11.7
of the C99 spec.

In the final analysis, while it may not be an
error per C89, and it may be an error per C99,
it's probably not something we need to be too
concerned about.

http://gcc.gnu.org/onlinedocs/gcc-3....html#Standards

Regards,
Larry

--
Anti-spam address, change each 'X' to '.' to reply directly.
Nov 14 '05 #12
Dan Pop wrote:
As for why the message about line 2 is wrong, here is the chapter and
verse from the C standard:

15 For two function types to be compatible, both shall specify
compatible return types. Moreover, the parameter type lists,
if both are present, shall agree in the number of parameters and
in use of the ellipsis terminator; corresponding parameters shall
have compatible types. If one type has a parameter type list
and the other type is specified by a function declarator that
is not part of a function definition and that contains an empty
identifier list, the parameter list shall not have an ellipsis
terminator and the type of each parameter shall be compatible
with the type that results from the application of the default
argument promotions...

Which means that

int f(int);
int f();

is OK, but

int f(float);
int f();

is not. nl main.c 1 int f(float);
2 int f();
3 int f(float x) { return 0; }
4
5 int main (void) { return 0; }
6
gcc -Wall -std=c99 -pedantic -o main main.c

main.c:2: error: conflicting types for `f'
main.c:2: error: an argument type that has a default promotion can't
match an empty parameter name list declaration
main.c:1: error: previous declaration of `f'
main.c:3: error: conflicting types for `f'
main.c:3: error: an argument type that has a default promotion can't
match an empty parameter name list declaration
main.c:2: error: previous declaration of `f'
Nov 14 '05 #13
In <cb***********@f1n1.spenet.wfu.edu> Allin Cottrell <co******@wfu.edu> writes:
Dan Pop wrote:
In <cb***********@f1n1.spenet.wfu.edu> Allin Cottrell <co******@wfu.edu> writes:

Thomas Heinz wrote (in re. gcc compilation of this erroneous
program):

$ cat test.c
int f(int);
int f();
int f() {return 0;}

int main (void) { return 0; }
The only point which remains concerns the error statement for
the program ... which is:

test.c: In function f:
test.c:3: error: number of arguments doesn't match prototype
test.c:2: error: prototype declaration

Here, it would be nice if the prototype declaration (3rd line of
error statement) refers to the strictest declaration (in the
example line 1).

Interesting: that message does seem wrong, since there's no
inconsistency between lines 2 and 3, only between 1 and 3.


The message about line 2 *is* wrong. Note, however, that, if I fix line 3
the message about line 2 goes away:

fangorn:~/tmp 48> cat test.c
int f(int);
int f();
int f(int i) {return 0;}
fangorn:~/tmp 49> gcc -c test.c
fangorn:~/tmp 50>


Fine, I don't find that surprising.


I do: changing line 3 didn't affect the relatioship between line 1 and 2
in *any* way, did it?
So, we have no conformance issue: the original code *required* at least
one diagnostic and got it. The correct code was correctly translated.


I guess my question is, where do conformance issues end and QoI issues
begin? You say, "the original code *required* at least one diagnostic
and got it". True, but what if the diagnostic had been:

test.c:666: error: elephants are trampling your begonias

The point that Thomas Heinz observed is that

test.c:2: error: prototype declaration

is not much better (though I accept the first diagnostic line given
by gcc was perfectly correct).


OTOH, if, after fixing line 3, gcc still treated line 2 as an error (i.e.
no object code was generated), there would have been a conformance
problem. There are enough loopholes in the standard for any language
lawyer to "solve" it, but gcc users would have had a valid reason for
complaining.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #14

On Thu, 24 Jun 2004, Larry I Smith wrote:

Dan Pop wrote:
In <cb***********@f1n1.spenet.wfu.edu> Allin Cottrell <co******@wfu.edu> writes:

$ cat test.c
int f(int);
int f();
int f() {return 0;}
[correctly produces an error on gcc, but said error has weird contents]
[...Dan quotes Standard...] Which means that

int f(int);
int f();

is OK, but

int f(float);
int f();

is not.

Well, ok Dan, you are correct.

But in my defense, I was taught that this was
a bad programming practice (2 conflicting prototypes
for the same function).
Two conflicting prototypes for the same function is not merely a
"bad programming practice"; it is an ERROR. (From N869: A function
prototype is a declaration of a function that declares the types of
its parameters.)
The GNU WEB site
(By the way, I'm fairly certain GNU does not have a WEB site. WEB
is Knuth territory. GNU may very well have a website, or a site on
the WWW. ;)
states that once the C99 spec is
fully supported by GCC that it (C99) will become the
default mode for GCC. Once that is done, the
'int promotion' assumption will no longer be
supported
I think you are referring to "implicit int." (This is just
a pet rule of thumb, and I wouldn't force it on you, but I only
use quote marks when I'm actually quoting something. "int
promotion" isn't quoted from anywhere, least of all the GCC
website, so it was a little weird.)
"Implicit int" is the rule that allows in C90 programs

main()
{
auto i;
...

This is ruled out (AFAICT) by N869 6.7.2#2, "At least one type
specifier shall be given in the declaration specifiers in each
declaration...," where a 'type-specifier' is for example 'int'
or 'long'.
and f() will no longer be assumed to
be the same as f(int).
'f()' and 'f(int)' have never been even remotely similar in any
flavor of C, except that you can put them both in the context
'int ~;' and get (different) valid function declarations.
Per the CGG 'checklist'
of C99 conformance, some of this has already been
done. So, what we may be seeing here is partial
implementation of the C99 spec in the error handling
code. This is also mentioned in 6.11.6 and 6.11.7
of the C99 spec.
For my own selfish benefit: Is this 6.11.4 and 6.11.5 of
the N869 draft? The former talks about function declarators
such as 'int f();' in the original example, and the latter
talks about function definitions such as 'int f(f) int f; {}'.
In the final analysis, while it may not be an
error per C89,
It is.
and it may be an error per C99,
It is.
it's probably not something we need to be too
concerned about.


But it is (read: appears to be) so easy to fix, there's no
reason *not* to fix it right away.

-Arthur

Nov 14 '05 #15
Arthur J. O'Dwyer wrote:
On Thu, 24 Jun 2004, Larry I Smith wrote:
it's probably not something we need to be too
concerned about.

But it is (read: appears to be) so easy to fix, there's no
reason *not* to fix it right away.

-Arthur


I meant that there's no need to be too concerned about
this being a GCC internal bug; since that was the OP
question that started this thread.

Dan says the double prototype is not an error (and includes
text from the spec to support his position).
Yet, you say it is always an error.
Which position is correct? No wonder some of us get confused.....

Regards,
Larry

--
Anti-spam address, change each 'X' to '.' to reply directly.
Nov 14 '05 #16
In <L%*******************@nwrddc01.gnilink.net> Larry I Smith <la***********@verizon.net> writes:
Dan says the double prototype is not an error (and includes
text from the spec to support his position).


I merely said that, in this particular case, a prototype and a
non-prototype declaration for the same function are not an error. I have
also provided an example where they are an error.

I didn't address any double prototype issue.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #17
Dan Pop wrote:
In <L%*******************@nwrddc01.gnilink.net> Larry I Smith <la***********@verizon.net> writes:

Dan says the double prototype is not an error (and includes
text from the spec to support his position).

I merely said that, in this particular case, a prototype and a
non-prototype declaration for the same function are not an error. I have
also provided an example where they are an error.

I didn't address any double prototype issue.

Dan


Ok, I get it. My error in assumption was that I interpreted
both lines (1 & 2) as prototypes; that's the way I was
trained - sorry.

I think we've beaten this horse enough....

Regards,
Larry

--
Anti-spam address, change each 'X' to '.' to reply directly.
Nov 14 '05 #18
Allin Cottrell wrote:
Peter Ammon wrote:
Allin Cottrell wrote:
Thomas Heinz wrote (in re. gcc compilation of this erroneous
program):

$ cat test.c
int f(int);
int f();
int f() {return 0;}

int main (void) { return 0; }

The only point which remains concerns the error statement for
the program ... which is:

test.c: In function f:
test.c:3: error: number of arguments doesn't match prototype
test.c:2: error: prototype declaration

Here, it would be nice if the prototype declaration (3rd line of
error statement) refers to the strictest declaration (in the
example line 1).


Interesting: that message does seem wrong, since there's no
inconsistency between lines 2 and 3, only between 1 and 3.

I'm cc'ing comp.lang.c.

Allin Cottrell.


Here's my take, FWIW.

Line 1 declares a function f() returning int and taking one parameter
of type int.

Line 2 declares a function f(). It is not a prototype (I think Larry
Smith is wrong on this issue). Since the return types are the same,
the declarations are compatible. Notice if you change the return type
to float, you get an error.

Agreed.

Line 3 declares a function f(). This declaration is not a prototype,
so no problem. Line 3 also defines a function int f(void). The
definition does not match the prototype in line 1, and hence the error.

Again, agreed. The issue raised by Thomas is just this: the
disagreement is between the prototype on line 1 and the function
definition on line 3, yet the gcc error message refers to a
"prototype" on line 2.


Sorry, I missed that point. I agree that the compiler's error message
is wrong (in the sense that its explanation is wrong; the standard
permits wrong explanations AFAIK).
Nov 14 '05 #19
Arthur J. O'Dwyer wrote:

[...]

Peter Ammon's
answer to your question is correct AFAICT (but I'm curious about
the 'void foo()' examples at the end of his post... chapter and
verse, Peter?).


[..]

My examples are reproduced below:

--
Notice you can do weird stuff with this declaration/definition disconnect.

void foo() {
foo(5);
foo(3.5);
foo("hello");
}

should compile as C, even though it's obviously illegal. But change it to

void foo() {
void foo(int);
}

and you'll get an error.
--

I'm afraid I'm empty handed regarding chapter and verse. I think I got
the impression that this code must compile from an old clc post (which I
cannot locate) by Chris Torek, though in the case I'm wrong I certainly
don't mean to incriminate him. Heck, he's named in the headers in my OS.

-Peter
Nov 14 '05 #20
Arthur J. O'Dwyer wrote:
On Thu, 24 Jun 2004, Larry I Smith wrote:
The GNU WEB site

(By the way, I'm fairly certain GNU does not have a WEB site. WEB
is Knuth territory. GNU may very well have a website, or a site on
the WWW. ;)
-Arthur


Hmm, here's the result of a google 'define:WEB site' search:

"A collection of "pages" or files linked together and available on the
World Wide Web. Web sites are provided by companies, organizations and
individuals."

"WEB site" or "website", six of one and a half-dozen of the other.

If it's the uppercase (i.e. WEB) that you're addressing, it's
a habit because that's how it must be in all documentation
written at my place of employment - per the "Documentation Police" (:

Regards,
Larry

--
Anti-spam address, change each 'X' to '.' to reply directly.
Nov 14 '05 #21
Dan Pop wrote:
In <cb***********@f1n1.spenet.wfu.edu> Allin Cottrell <co******@wfu.edu> writes:

Dan Pop wrote:
In <cb***********@f1n1.spenet.wfu.edu> Allin Cottrell <co******@wfu.edu> writes:

Thomas Heinz wrote (in re. gcc compilation of this erroneous
program):

$ cat test.c
int f(int);
int f();
int f() {return 0;}

int main (void) { return 0; }

>The only point which remains concerns the error statement for
>the program ... which is:
>
>test.c: In function f:
>test.c:3: error: number of arguments doesn't match prototype
>test.c:2: error: prototype declaration
>
>Here, it would be nice if the prototype declaration (3rd line of
>error statement) refers to the strictest declaration (in the
>example line 1).

Interesting: that message does seem wrong, since there's no
inconsistency between lines 2 and 3, only between 1 and 3.

The message about line 2 *is* wrong. Note, however, that, if I fix line 3
the message about line 2 goes away:

fangorn:~/tmp 48> cat test.c
int f(int);
int f();
int f(int i) {return 0;}
fangorn:~/tmp 49> gcc -c test.c
fangorn:~/tmp 50>


Fine, I don't find that surprising.


I do: changing line 3 didn't affect the relatioship between line 1 and 2
in *any* way, did it?


I think you are (unusally) being obtuse here. I was not surprised that
the gcc diagnostic disappeared when line 3 was deleted for the simple
reason that, without line 3, the program was correct -- and I respect
gcc sufficiently that I do not generally expect it to emit diagnostics
for correct C programs.

Your rejoinder -- namely, that the deletion of line 3 does not alter
the relationship between lines 1 and 2 -- is beside the point, which
was, to restate it one more time, that an inconsistency in the full
program between lines 1 and 3 was misleadingly flagged by gcc as
an inconsistency between lines 2 and 3.

Allin Cottrell
Nov 14 '05 #22
In <cb***********@f1n1.spenet.wfu.edu> Allin Cottrell <co******@wfu.edu> writes:
Dan Pop wrote:
In <cb***********@f1n1.spenet.wfu.edu> Allin Cottrell <co******@wfu.edu> writes:

Dan Pop wrote:

In <cb***********@f1n1.spenet.wfu.edu> Allin Cottrell <co******@wfu.edu> writes:

>Thomas Heinz wrote (in re. gcc compilation of this erroneous
>program):
>
>$ cat test.c
>int f(int);
>int f();
>int f() {return 0;}
>
>int main (void) { return 0; }
>
>
>
>>The only point which remains concerns the error statement for
>>the program ... which is:
>>
>>test.c: In function f:
>>test.c:3: error: number of arguments doesn't match prototype
>>test.c:2: error: prototype declaration
>>
>>Here, it would be nice if the prototype declaration (3rd line of
>>error statement) refers to the strictest declaration (in the
>>example line 1).
>
>Interesting: that message does seem wrong, since there's no
>inconsistency between lines 2 and 3, only between 1 and 3.

The message about line 2 *is* wrong. Note, however, that, if I fix line 3
the message about line 2 goes away:

fangorn:~/tmp 48> cat test.c
int f(int);
int f();
int f(int i) {return 0;}
fangorn:~/tmp 49> gcc -c test.c
fangorn:~/tmp 50>

Fine, I don't find that surprising.
I do: changing line 3 didn't affect the relatioship between line 1 and 2
in *any* way, did it?


I think you are (unusally) being obtuse here. I was not surprised that


I don't. See below.
the gcc diagnostic disappeared when line 3 was deleted for the simple
reason that, without line 3, the program was correct -- and I respect
gcc sufficiently that I do not generally expect it to emit diagnostics
for correct C programs.
OTOH, do you expect it to emit *bogus* diagnostics for incorrect programs,
when then mistake occurs *later* than the diagnosed line? Note, that,
in the program under discussion, there was no conflict between lines 2 and
3.
Your rejoinder -- namely, that the deletion of line 3 does not alter
the relationship between lines 1 and 2 -- is beside the point, which
was, to restate it one more time, that an inconsistency in the full
program between lines 1 and 3 was misleadingly flagged by gcc as
an inconsistency between lines 2 and 3.


It is a matter of how you interpret the diagnostic in question:
as complaining about an inconsistency between lines 1 and 2
or as complaining about an inconsistency between lines 2 and 3.
The diagnostic being "prototype declaration", and pointing to line 2,
it only makes sense to treat it as complaining about the relationship
between lines 1 and 2 (there is no prototype declaration in either
line 2 or line 3).

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #23
On Wed, 23 Jun 2004 19:40:42 -0400, Allin Cottrell <co******@wfu.edu>
wrote:
Dan Pop wrote:
In <cb***********@f1n1.spenet.wfu.edu> Allin Cottrell <co******@wfu.edu> writes: [gcc message pointing to wrong 'prototype' for declaration conflict]
So, we have no conformance issue: the original code *required* at least
one diagnostic and got it. The correct code was correctly translated.


I guess my question is, where do conformance issues end and QoI issues
begin? You say, "the original code *required* at least one diagnostic
and got it". True, but what if the diagnostic had been:

test.c:666: error: elephants are trampling your begonias

QoI takes over pretty early. Dan (probably deliberately) restated in
passing the Standard's requirement, from (C99) 5.1.1.3p1:
A conforming implementation shall produce at least one diagnostic
message (identified in
an implementation-defined manner) if a preprocessing translation unit
or translation unit
contains a violation of any syntax rule or constraint, even if the
behavior is also explicitly
specified as undefined or implementation-defined. Diagnostic messages
need not be
produced in other circumstances.8)

same in C89 except for the "even if" clause, which actually seems to
be superfluous; and referring to footnote 8 or 6 respectively, but
footnotes are not normative:
The intent is that an implementation should identify the nature of,
and where possible localize, each
violation. Of course, an implementation is free to produce any number
of diagnostics as long as a
valid program is still correctly translated. It may also successfully
translate an invalid program.

Thus diagnostics are not *required* to identify or describe the error,
or even to be one per detected error; a compiler with the (in)famous
'ed' behavior of simply printing a single question mark '?' for any
error or combination of errors would be conforming, at least in that
respect; and moreover since an implementation may produce any
diagnostics it likes beyond the required one(s), a compiler that
printed a single question mark for every sourcefile, with errors or
without, would also be conforming, but perverse. Even if both beer and
speech free it wouldn't attract or deserve many users.

Your particular example warning is therefore conforming; but for me
useless since I happen not to have any begonias -- so it would
intrigue me what -W flag gcc would use to disable (or enable?) it:
maybe -W[no-]pachyderm-deflorestation ?-)

- David.Thompson1 at worldnet.att.net
Nov 14 '05 #24

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

12 posts views Thread by Michael Foord | last post: by
8 posts views Thread by Elf M. Sternberg | last post: by
8 posts views Thread by Robert | last post: by
5 posts views Thread by jmdocherty | last post: by
43 posts views Thread by michael.f.ellis | last post: by
6 posts views Thread by Rex the Strange | last post: by
1 post views Thread by CARIGAR | last post: by
xarzu
2 posts views Thread by xarzu | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.