1

I just debugged a C program for a long time, only to find that I missed an argument when making a function call, so junk instead filled the missing argument. Stupid mistakes like this are really frustrating, but I suppose compilers should be able to detect this. (C doesn't even support default arguments; even in C++, default arguments need to be explicitly declared.)

Update: The prototype was found to be wrong, too...

So, is there a GCC flag for warning unmatched function call argument number? I always have -Wall and -pedantic on; it's quite surprising that such an obvious error goes undetected. (Actually I suppose there is some reason that GCC does not report, but I can't think of any at this time.)

Embarrassing code example:

    static void dfs();

    int main(int argc, const char *argv[]) {
         dfs(1);
    }

    static void
    dfs(int remain, int last) {
        // dfs
    }

Another discovery I just made is that if the prototype contains argument, the compiler will report; but the prototype happened to contains no arguments, then the compiler just slipped.

4ae1e1
  • 6,220
  • 7
  • 40
  • 70
  • 1
    In addition to `-Wall` and `-pedantic`, I use `-Wextra`. Perhaps that enables the warning you desire? – icktoofay Mar 31 '13 at 05:00
  • If you've properly declared your functions, this should happen by default. – Barmar Mar 31 '13 at 05:01
  • 1
    Code? You're probably doing something else wrong. – vanza Mar 31 '13 at 05:01
  • @Barmar Good point... Just checked my prototype... It was also wrong -_-|| But the function was declared `static`. If a static function's implementation does not match declaration, GCC should also report, right? Even more confused now... – 4ae1e1 Mar 31 '13 at 05:05
  • 1
    Only if the declaration and definition are in the same translation unit. Did you include the header containing your declarations in your implementation file? It's a bit weird to declare a static function in a header file though - what does that *mean*, exactly? – Carl Norum Mar 31 '13 at 05:08
  • @CarlNorum They are in the same file. `static` in the most static sense. I never mentioned a header file... – 4ae1e1 Mar 31 '13 at 05:09
  • Is one in an `#ifdef` block not getting included or something? Your problem seems bizarre to me. Can you show the code? An [SSCCE](http://sscce.org) will really help you figure this one out. – Carl Norum Mar 31 '13 at 05:10
  • @CarlNorum Just updated post. – 4ae1e1 Mar 31 '13 at 05:15
  • In C (but not C++) a prototype with `()` arguments disables argument checking. – Barmar Mar 31 '13 at 05:17
  • AHA! `dfs()` probably doesn't mean what you think it does. That is, it's not the same as `dfs(void)`. Link: http://stackoverflow.com/questions/693788/c-void-arguments – Carl Norum Mar 31 '13 at 05:18
  • @Barmar Well, then my wasted debugging can only be attributed to bad luck... Thanks. – 4ae1e1 Mar 31 '13 at 05:19
  • Maybe this should be closed as a duplicate, now? – Carl Norum Mar 31 '13 at 05:20
  • @CarlNorum Yeah, I know that; but I didn't know `void` can suppress argument checking in C. – 4ae1e1 Mar 31 '13 at 05:20
  • `void` *doesn't*. `()` without the `void` *does*. – Carl Norum Mar 31 '13 at 05:21
  • @CarlNorum No problem, as long as the problem is solved. – 4ae1e1 Mar 31 '13 at 05:21

2 Answers2

4

Unmatched number of function call arguments is a mandatory diagnostic that all compilers will and must provide without any special setting. It is mandated by the standard.

C99Standard 6.5.2.2 Function calls:
Constraints

If the expression that denotes the called function has a type that includes a prototype, the number of arguments shall agree with the number of parameters. Each argument shall have a type such that its value may be assigned to an object with the unqualified version of the type of its corresponding parameter.


 static void dfs();

Tells the compiler dfs is a static function which returns a void and can take unspecified number of arguments. Further you provide a definition for the function which takes 2 arguments & call the same. As you see there is no breaking of contract. The problem is the declaration of the function is incorrect. If you want to declare a function which takes no arguments you must use:

 static void dfs(void);

Once you do that the compiler will provide you a diagnostic.

Alok Save
  • 190,255
  • 43
  • 403
  • 518
  • This doesn't seem to answer his question, since he apparently did something that prevented the mandatory diagnostic. – Barmar Mar 31 '13 at 05:04
  • See comment above: the prototype was wrong, too (embarrasing...) But another problem arises: the function was declared `static`. If a static function's implementation does not match declaration, GCC should also report, right? – 4ae1e1 Mar 31 '13 at 05:07
  • @Barmar: Updated for your reference. It answers what the Q asks. OP not providing a short example of problem situation has nothing to do with the fact that standard mandates this diagnostic. – Alok Save Mar 31 '13 at 05:10
  • @KevinSayHi: If you need an answer and not guess then you shhould be posting an SSCCE of your problem case. – Alok Save Mar 31 '13 at 05:14
  • @KevinSayHi: Hope that answers. – Alok Save Mar 31 '13 at 05:23
0

There are various options you can use:

  • -Wstrict-prototypes
  • -Wmissing-prototypes
  • -Wold-style-definition
  • -Wold-style-declaration

These work even if you're not using -std=c99 or something similar. I'm plagued by antique code at the office and use these (except -Wstrict-prototypes) when I'm cleaning up some code that hasn't been given 'the treatment'. The exception is because the pointers to functions in the code base are mostly without the necessary argument lists. For personal code, or code I'm in charge of, this isn't a problem.

Jonathan Leffler
  • 666,971
  • 126
  • 813
  • 1,185