7

I would like to find out which is the most extreme error checking flag combination for g++ (4.7). We are not using the new C++11 specification, since we need to cross compile the code with older compilers, and these older compilers (mostly g++ 4.0) often cause problems which simply are ignored by the g++4.7.

Right now we use the following set of flags:

-Wall -Wcomment -Wformat -Winit-self -ansi -pedantic-errors \
-Wno-long-long -Wmissing-include-dirs -Werror -Wextra

but this combination does not identify issues such as a double being passed in to a function which expects int, or comparison between signed and unsigned int and this causes the old compiler to choke on it.

I have read through the documentation and -Wsign-compare should be enabled by -Wextra but in practice seems this is not the case, so I might have missed something...

sehe
  • 374,641
  • 47
  • 450
  • 633
Ferenc Deak
  • 34,348
  • 17
  • 99
  • 167
  • 2
    "this combination does not identify issues such as a double being passed in to a function which expects int" -- that's not an error, just a narrowing conversion (`-Wconversion`). Unfortunately gcc gives a meaning to the word "pedantic" (specifically about standard conformance) which is different from how you've used it in the question ;-) Do you want a sort of union of every warning that every compiler author in the world has ever issued? The usual procedure is to read through the gcc manual and pick what you like. – Steve Jessop Jan 29 '13 at 09:09
  • That is when `-Weverything` (from Clang) is so interesting, it may not identify everything you need (if it's not implemented, it's not detected), but at the very least you don't have to run after the flags... – Matthieu M. Jan 29 '13 at 09:10
  • the best would be to compile with different compiler versions and see if they compile. This can be done as a CI job – BЈовић Jan 29 '13 at 09:12
  • @SteveJessop `-WConversion` fails with the Qt headers, we are using, that's why it's not included here :( – Ferenc Deak Jan 29 '13 at 09:14
  • 1
    @fritzone: so presumably if you were using clang then you'd start with `-Weverything`, discover that some warnings from Qt headers are intractable, and end up with `-Weverything -Wno-conversion -Wno-something-else`. In which case the answer is no, gcc doesn't have an option that lets you work like that. – Steve Jessop Jan 29 '13 at 09:17
  • @BЈовић they compile nicely :) The problem is with the warnings the different compilers emit, since they are not in "sync". g++4.0 for a MIPS emits more warnings that g++4.7 on a plain x86 box :( – Ferenc Deak Jan 29 '13 at 09:18
  • Could it be that some of the flags you use actually disable some of the warnings? I only use `-Wall -Wextra` but I do see the signed/unsigned comparison warnings. – Vincent Zoonekynd Jan 29 '13 at 09:18
  • 2
    @fritzone: the warnings shouldn't need to be in sync. If *any* of them warns, then you pay attention to the warning until it is solved. Warnings (other than those diagnostics required by the standard) are an opinion from the compiler that something might need attention. By using several compilers/configurations you're soliciting more opinions. And it's natural that different compilers (even different versions of the same compiler) have different opinions. So, if you can get your code to compile with clang then you can use it as a source of warnings. – Steve Jessop Jan 29 '13 at 09:20
  • why not just use `-Wall`? – user1095108 Jan 29 '13 at 09:23
  • @user1095108: Because `-Wall` is very, very, VERY far from being really all warnings. It should really have been called "-Wdefault", but historical reasons are quite strong sometimes. – Jan Hudec Jan 29 '13 at 09:27
  • @SteveJessop yes, that's the approach we use. Compile the code with all the available compilers we have (currently this includes g++47, g++40(cross for mips), g++46 and MSVS2010) and fix all the warnings. I was just surprised that the older compiler spits out more warnings than the new one (with the same level of warnings). I will definitely give a shot to clang to see what happens. – Ferenc Deak Jan 29 '13 at 09:31
  • It *might* not be the compiler version that makes the difference. Conceivably there are issues that gcc can/will diagnose when targeting MIPS but not when targeting x86. Obviously you'd hope that they'd be picked up as portability issues regardless of the target. But just for example if you use `intN_t` types, and they're defined to different standard types on different platforms, then you can get different warnings when using them. – Steve Jessop Jan 29 '13 at 09:35
  • Use a lint tool instead. – Hans Passant Jan 29 '13 at 11:18

2 Answers2

3

The -ansi is alias for the default standard without GNU extensions. I'd suggest instead being explicit using -std=c++98, but it should be default for g++ -ansi, so not really different.

But generally I've never seen anything that would be accepted by newer gcc and rejected by older gcc on the grounds of being invalid. I suspect any such problem is a bug in the older compiler or it's standard library. Gcc does not have warnings for things that are correct, but didn't work with older versions of it, so you don't have any other option than to test with the older version.

As for the specific issues you mention:

  • Passing double to function that expects int is not an error. It might be undefined behaviour though. -Wconversion should help.
  • Comparing signed with unsigned is also well defined, also always worked as defined and in case of equality comparisons actually makes programmers write worse code (comparing unsigned variable larger than int with -1 is something else than comparing it with -1u). So I actually always compile with -Wno-sign-compare.

The compiler should not print warnings for headers found in directories given with -isystem instead of -I, so that should let you silence the warning for Qt headers and keep it enabled for your own code. So you should be able to use -Wconversion.

Jan Hudec
  • 73,652
  • 13
  • 125
  • 172
  • there are a lot of things which older compilers do not accept and newer compilers do accept, such as ambiguity resolving between conflicting specialized templates... we had a lot of these too :) – Ferenc Deak Jan 29 '13 at 09:33
  • @fritzone: Yes. But they are _bugs_ in the older compiler. And the compiler generally does not provide warning for things that are correct, but didn't work in older version of that compiler, so for this kind of things you will have to test with the older version. – Jan Hudec Jan 29 '13 at 09:36
  • @fritzone: Or at least gcc does not provide such warnings. I've seen at least one such warning in MSVC. – Jan Hudec Jan 29 '13 at 09:38
1

Use lint or some other static analysis tool to check the code, in addition to compiler. On my Linux distro, apt-get install splint will get splint, maybe check if that has been packaged for your OS for easy installation.

hyde
  • 60,639
  • 21
  • 115
  • 176