ccompiler-warningslintgcc-warningfunction-prototypes

Compiler warning for function defined without prototype in scope?


[Question inspired by a comment thread at this answer.]

As everyone knows, since C99 it's an error to call a function that hasn't been declared, preferably with a proper prototype.

But, going beyond that, I want my compiler to warn me if I define a function without a prototype declaration in scope, presumably included out of the same header file that the callers are using. (Unless the function is static, in which case all of this is moot.)

The reason should be obvious: If there's a prototype declaration in a header, and it's included by all the callers, but it's not included in the file where the function is defined, and if the function's actual definition somehow differs from the external prototype, then all the prototype checking done on behalf the callers is worthless, and in fact counterproductively wrong. There's a glaring error, but it's not guaranteed to be caught at all.

Are there common compilers which can check this? I tried both gcc and clang with -Wall, and they don't. (I would imagine Gimpel lint -- if it's still around -- would do this, but I don't have a copy.)

Ideally, I'd like it to also insist that the prototype exist in a separate header file, but that's different kettle of fish, so I don't insist on it. (The reason for this additional stipulation would be that some programmers, harried by the hypothetical warning message, might try to silence it by typing in an external prototype at the top of the .c file containing the definition, which, again, would defeat the purpose.)


Solution

  • If you need an option which works on both gcc and clang, your best bet is probably -Wmissing-prototypes. As indicated in the gcc documentation, this will trigger if a global function is defined and either:

    It does not complain if the previous declaration is contained in the same file as the definition; that is, it does not require that the declaration be in a header file.

    This option must be enabled explicitly; it is neither enabled by -Wall nor by -Wextra.

    Unfortunately, gcc only allows that option for C and Objective C; not for C++ (presumably because C++ does not allow non-prototyped function declarations). For gcc, another possibility would be -Wmissing-declarations. This warning is only produced if there was no previous declaration; a previous declaration with no prototype (i.e. int foo();) is not reported. But it works on both C and C++. Again, the warning option must be enabled explicitly.

    Clang also has a -Wmissing-declarations option, but it means something completely different and it is enabled automatically (even if there are no -W options). For example, this option controls the complaints about empty declarations (int;), empty typedefs (typedef int;) and untagged composites which don't declare any object (struct { int a; };). Gcc also issues warnings about these constructs, but there is no obvious option to enable or disable these warnings.