views:

356

answers:

3

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
+7  A: 

-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).
Chris Jester-Young
+8  A: 
AndreyT
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
@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.
AndreyT
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.
AndreyT
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
@Eric: See the "EDIT" section of my answer.
AndreyT
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
@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")
AndreyT
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
@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++.
AndreyT
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
A: 

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