8

I currently have a project that uses g++ to compile it's code. I'm in the process of cleaning up the code, and I'd like to ensure that all functions have prototypes, to ensure things like const char * are correctly handled. Unfortunately, g++ complains when I try to specify -Wmissing-prototypes:

g++ -Wmissing-prototypes -Wall -Werror -c foo.cpp
cc1plus: warning: command line option "-Wmissing-prototypes" is valid for Ada/C/ObjC but not for C++

Can someone tell me:
1) Why does gcc this isn't valid? Is this a bug in gcc?
2) Is there a way to turn on this warning?

EDIT:

Here's a cut and paste example:

cat > foo.cpp <<EOF
void myfunc(int arg1, int arg2)
{
    /* do stuff with arg1, arg2 */
}
EOF
g++ -Wmissing-prototypes -c foo.cpp  # complains about not valid
g++ -c foo.cpp                       # no warnings
# Compile in C mode, warning appears as expected:
g++ -x c -Wmissing-prototypes -c foo.cpp
Roman C
  • 49,761
  • 33
  • 66
  • 176
Eric
  • 5,137
  • 4
  • 34
  • 31
  • I'm confused how that foo.cpp file should ever yield a "no prototype" warning. Your shown function definition *does* include a prototype. – Johannes Schaub - litb Mar 05 '10 at 23:00
  • May-be rather than just asking how to turn on warnings that appear to make no sense in C++ (as the warning says), you post some example what kind of error it is that you want to catch that the C++ compiler already doesn't catch ("ensuring that `const char*` are correctly handled")? – UncleBens Mar 06 '10 at 01:12
  • Where do you see a prototype? The example code doesn't include a header file, and it doesn't have a separate prototype line in the foo.cpp file. – Eric Mar 08 '10 at 15:41
  • 2
    The problem I want to catch is where someone changes the definition of a function in a .cpp file, but forgets to change the header file. With the warning, *that* developer would get an error (assuming I also have -Werror on), and he'd be able to fix it right away. Without the warning, *some other* developer, that uses the library the first developer wrote, would get a hard to track down error while linking his program, and once he figures out what's wrong the overhead of fixing the issue is hugely increased. – Eric Mar 08 '10 at 15:44

3 Answers3

10

When you compile a file with .cpp extension, it is compiled as C++ code by default. In C++ language the requirement for function declarations is a mandatory, hard requirement. There's no point in making an -Wmissing-prototypes option for C++.

In other words, you can't "turn on this warning" in C++ because "missing prototype" is always an error in C++.

P.S. As a side note: The notion of prototype is specific to C language only. There are no "prototypes" in C++.

In C language a function declaration can be a prototype or not a prototype, hence the need for an extra term to distinguish ones from the others. In C++ function declarations are always "prototypes" (from C point of view), so in C++ there simply no need for this extra term. In C++ function declarations are simply function declarations. That just says it all.

EDIT: After reading your comment I came to conclusion that you must have misunderstood the meaning and the purpose of the -Wmissing-prototypes option and corresponding warning. Note, this option will not check whether you have included prototypes of all your functions into some header file. There is no option to do that in GCC, regardless of whether you are using C or C++.

The purpose of -Wmissing-prototypes is different. This option only works when you call a function that has no visible prototype at the point of the call. In C language doing this is legal, but if you'd like a warning in this case, you use -Wmissing-prototypes option. In C++ language calling a function that has no visible declaration ("prototype") at the point of the call is always an immediate error, which is why C++ compilers have no need for such option as -Wmissing-prototypes.

In other words, if you defined some function in some implementation file, but forgot to include a prototype for this function in some header file, you will not get any warnings from the compiler until you actually try to call that function. It doesn't matter whether your code is C or C++, whether you use -Wmissing-prototypes or not... Until you make an attempt to call the function, there will be no warnings.

But once you try to call a function without a prototype, the C compiler will report a warning (if you used -Wmissing-prototypes) and C++ compiler will always report an error.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • That's not true, at least not with gcc. It will happily compile a .cpp file that has functions without a prototype. This means I can have foo.cpp with a function implemented as void myfunc(int arg1, int arg2) { /* use arg1 and arg2 */ } but if the header file says void myfunc(int arg1); then any the callers will be out of sync, and there won't be any indication of that from the compiler! – Eric Mar 05 '10 at 19:21
  • 3
    @Eric: Sorry, but what you are saying makes no sense. Firstly, in C++ the compiler *will not allow you* to call an undeclared function, period. Secondly, your example with `myfunc` is completely irrlevant. In C++ `myfunc(int, int)` and `myfunc(int)` are *two completely different* (overloaded) functions. Callers will not be "out of sync". Callers will simply call another function (assuming is defined as well). That's a matter of your intent, not a matter of "indication from the compiler". There's no error/problem in it in C++, so expecting something from the compiler would be rather strange. – AnT stands with Russia Mar 05 '10 at 19:48
  • 2
    If you forget to define `myfunc(int)`, then you'll get an error from linker, of course. But again, `myfunc(int)` and `myfunc(int, int)` are two completely different independent functions in C++. It is your responsibility to declare and call the right one. If you call `myfunc(int)`, the compiler will assume that that's what you wanted. If you actaully wanted to call `myfunc(int, int)` but called `myfunc(int)` by mistake... sorry, the compiler cannot read your mind to figure which one you actually *wanted* to call. – AnT stands with Russia Mar 05 '10 at 19:51
  • Ok, so I'd get an error from the linker. That's better than nothing, but it makes problems harder to track down than necessary b/c the error is pointing at the wrong location, and that's assuming I even actually get to the final link stage. e.g.: if I'm working on a shared library, and change one of the interfaces, the problem might not show up until considerably later when I (or someone else even!) goes and tries to use the shared library to link a final program. Instead of it being a 30 second fix because I noticed right it when compiling that file, it might take days! – Eric Mar 05 '10 at 20:15
  • @Eric: See the "EDIT" section of my answer. – AnT stands with Russia Mar 05 '10 at 20:17
  • 2
    err... the gcc man page clearly says "defined", not "called" for -Wmissing-prototypes: "Warn if a global function is defined without a previous prototype declaration." Try the example I included in the question; it'll be quite clear that I'm not misunderstanding the meaning of the option. The option that turns on warnings when *calling* a function is -Wimplicit-function-declaration (aka -Wimplicit) – Eric Mar 05 '10 at 20:51
  • 1
    @Eric: Oh, my mistake. Thanks for clearing that up for me. In that case... well, I guess the option would indeed make sense for C++ as well. Could it be that it is just spelled differently? (Since C++ doesn't normally use the term "prototype") – AnT stands with Russia Mar 05 '10 at 21:06
  • I think it's just not supported. I finally found an old "closed" bug (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=13687) that complains about this same problem. I opened a new bug (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43272) with what is hopefully a more persuasive argument for allowing this warning. – Eric Mar 05 '10 at 21:20
  • 1
    @Eric: But again, the ultimate purpose of the `-Wmissing-prototypes` is to prevent the calls without the prototype. I.e. the `-Wmissing-prototypes` is related to `-Wimplicit`. The former is intended as a preventative measure, while the latter is more of an immediate per-case report. In C++ again, the whole issue of a "call without prototype" is different. You simply can't make such a call in C++, which is why `-Wmissing-prototypes` might be seen as significantly less useful in C++. – AnT stands with Russia Mar 05 '10 at 21:25
  • IMO, that's an argument FOR having -Wmissing-prototypes! If you can't make a call in C++ w/o a prototype, the compiler should tell you that you're missing the prototype! And it should do so at the moment during a build when you can actually do something about it. In c++, -Wmissing-prototypes doesn't just prevent calls without the prototype, but it would prevent calls with the WRONG prototype. – Eric Mar 08 '10 at 15:40
8

-Wmissing-prototypes is not applicable for C++, because C++ always requires prototypes.

Take the following declaration for example:

void foo();
  • In C, foo can be called with any number and type of arguments.
  • In C++, foo does not take any arguments (compilation error if any arguments passed in).
C. K. Young
  • 219,335
  • 46
  • 382
  • 435
5

Did you try -Wmissing-declarations? That seems to work for g++ and detect the error case you describe. I'm not sure which version they added it in, but it works for me in 4.3.3.

Steve Onorato
  • 397
  • 4
  • 10
  • Thanks, that seems to be what I need. Now I just need to figure out how to upgrade the version of GCC on my RHEL5 machines. – Eric Apr 09 '13 at 17:53