Bug 48091 - No warning when given function arguments mismatch earlier function definition which GCC assumes to be K&R, even with --std=c99 -pedantic
Summary: No warning when given function arguments mismatch earlier function definition...
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 4.4.5
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
Depends on:
Reported: 2011-03-12 09:36 UTC by Eero Tamminen
Modified: 2017-01-23 16:47 UTC (History)
0 users

See Also:
Known to work:
Known to fail:
Last reconfirmed: 2017-01-23 00:00:00


Note You need to log in before you can comment on or make changes to this bug.
Description Eero Tamminen 2011-03-12 09:36:51 UTC
int test(a, b)
        int a;
        int b;
        return a+b;
int main(void)
        return test("foo");

With all of these compiler options:
- gcc -Wall -Wextra --std=c99 -pedantic -O test.c

The expected output is similar to other compilers i.e.:
- a warning about arguments mismatching
  (As all argument types and number of them are fully specified), or
- warning about incomplete function definition

Actual outcome:
- No warnings about anything

(With -O2, GCC inlines the function and then finds a mismatch and I of course can use -Wold-style-definition warning option, but that's beside the point.)

GCC version:
- 4.4.5 in Debian Squeeze
Comment 1 Richard Biener 2011-03-14 10:33:21 UTC
That's how K&R works.  The function definition isn't a prototype.
Comment 2 Eero Tamminen 2011-03-17 21:08:41 UTC
(In reply to comment #1)
> That's how K&R works.  The function definition isn't a prototype.

Why that would be a valid excuse not to give a warning when function call either doesn't match or isn't known by GCC to match what the function accepts?  That makes no sense, especially when I'm requesting -Wall/-Wextra and/or pedantic C99 checking...

It's dangerous behavior and makes GCC look bad compared to about any other compiler that hasn't died on previous century. User might not know that the code he's compiling happens to contain (mismatching) K&R function definitions, silently hiding such errors when user has requested stricter checking is evil.

GCC should of course still accept K&R code (in case there's still K&R code that isn't dead or fixed), this bug is about giving warnings when function call doesn't match what GCC knows about the function.

If somebody doesn't want warnings on K&R function definitions (which became obsolete 22 years ago), they can always specifically disable such warnings.  Newer GCC being more strict and giving more warnings on the same code shouldn't come as a surprise to anybody.
Comment 3 Eero Tamminen 2011-03-30 17:59:26 UTC
Another example about how dangerous this default GCC behavior is.

Consider code A:
static int a, b;

void set_a(int i) {
        a = i;
void set_b(int i) {
        b = i;
int add() {
        return a+b;

And its usage from elsewhere:
#include <stdio.h>
int main(int argc, const char *argv[] __attribute__((unused)))
        return add(argc, 50);

GCC doesn't catch this because it assumes the code is obsolete K&R syntax without even bothering to give user a warning about it.  Even when user is requesting warnings with options like:
  gcc -Wall -Wextra --std=c99 -pedantic -O2 test.c

Code A) is *not* K&R.  Nowadays it's either C++ code copied to a C program or code from people who don't know or remember that only in C++ "add()" means void argument whereas in ANSI-C "add(void)" should be used.

I see this in (non-K&R) C sources all the time, it's very common mistake about which GCC doesn't bother to give any warning.

Comment 4 Eero Tamminen 2011-06-23 19:28:45 UTC
(In reply to comment #0)
> Program:
> ----------
> int test(a, b)
>         int a;
>         int b;
> {
>         return a+b;
> }
> int main(void)
> {
>         return test("foo");
> }
> ----------

(In reply to comment #1)
> That's how K&R works.  The function definition isn't a prototype.

Right, including an ANSI-C prototype either for:
  int test(int a, int b);

or for:
  int test(const char *);

Would cause there to be a warning.  I would never have though somebody to mix K&R & ANSI-C like that, but I just noticed that having K&R function implementations in *.c files with ANSI-C prototypes in headers seems to be e.g. how Glibc does things...

It still doesn't help with mistakes like "function() { ... }" for people who have experience with other compilers than GCC.  GCC is only compiler with this dangerous defaulting to K&R interpretation.
Comment 5 Jonathan Wakely 2017-01-23 12:59:20 UTC
A better example, which doesn't get any diagnostic even with -Wpedantic, is

void f() { }

int main()
  f(1, 2, 3);

C11 seems clear:

"An empty list in a function declarator that is part of a definition of that function specifies that the function has no parameters."
Comment 6 Jonathan Wakely 2017-01-23 13:10:08 UTC
Even if it's not invalid we should warn when we know the function has no parameters and it's called with arguments.
Comment 7 Joseph S. Myers 2017-01-23 16:19:08 UTC
This is valid code (or at least the version with the call inside if (0) or otherwise not known to be executed unconditionally for all executions of the program is).  See what I said in bug 64526 and DR#317 linked therefrom.
Comment 8 Jonathan Wakely 2017-01-23 16:47:26 UTC
OK, but as the reporter of 64526 said, we should warn at least. We know the number of parameters (even if there isn't a prototype) and we know the number of arguments doesn't match it. That warrants a warning.