问题
I know that one should always compile with both -Wall
and -Wextra
as they enable warnings and help us to understand our mistake, if any.
I've read that the -Wextra
compiler flag is not recommended to use because it is too verbose with a lot of false positives.
I was quite surprised on reading this. So I started googling about it but I didn't get any answer as all the search results showed was "what does the -Wextra
flag do?".
So, my questions are
- In which all situations does the
-Wextra
flag emit uneccessary warnings? - Is it possible to stop the
-Wextra
flag from enabling the other flags that cause GCC from emitting these types of warnings?
回答1:
The point about the usefulness of -Wextra
warnings is that the corresponding warnings have these properties (more or less):
They generate false positives.
The false positives are relatively frequent.
Adapting the code to avoid false positives is a nuisance.
The consequence is, that many projects that switch on -Wall -Wextra
give up trying to avoid all the warnings. Consequently, when you compile such a project, you see hundreds and hundreds of warnings, almost all about legit code. And the one warning that you should have seen slips unnoticed in the endless warning stream. Worse: the fact that a normal compilation spits out so many warnings makes you get sloppy about avoiding the new warnings that your new code introduces. Once a project reaches a few tens of warnings, the fight is usually over; it will require a heroic effort to bring the warning count back to zero.
Here is an example of some perfectly legitimate code that is barked at by -Wextra
:
void myClass_destruct(MyClass* me) {}
It's a destructor and it's empty. Yet, it should be there simply to facilitate calling it at the appropriate points (subclass destructors), so that it is easy to add stuff to MyClass
that needs cleanup. However, -Wextra
will bark at the unused me
parameter. This forces programmers to write code like this:
void myClass_destruct(MyClass* me) {
(void)me; //shut up the compiler barking about the unused parameter
}
This is plain noise. And it gets annoying to write such code. However, in order to achieve a zero warning count under a -Wextra
regime, this noise needs to be added to the code. So, you can pick any two of these three:
Clean code
Zero warning count
-Wextra
warnings
Choose wisely which one you want to drop, you won't get all three.
回答2:
Some of -Wextra
warnings are enforcing appropriate coding style which can conflict with some people processes. This is the only reason to avoid it. My solution in this case is to 'correct' exact set using -Wno-*
syntax.
For example -Wextra
implies -Wempty-body
which warns you about empty bodies of some control structures like if
, else
and while
. But if you follow from one side 'iterative' implementation style and from another want serious amount of warnings, this will be uncomfortable for you.
Here is evolving code example:
void doSomething()
{
if (validatePreConditions())
{
//TODO Handle it some time.
}
// ... Here you have real code.
}
If you have -Werror
, and want to start testing without pre-condition check implemeneted, you are in trouble.
But here is pitfall, what is acceptable for 'in-development' code is to be fixed by the time code is going to production. So my option for such cases is to have different set of warnings and different build profiles. So, for example, 'developer' build is OK to have empty bodies but anything going to be merged into main-line MUST NOT
have such gaps.
Another example is -Wignored-qualifiers
which is included into -Wextra
. In some cases you know compiler will ignore your const
qualifier but you're adding it just for your own comfort (I personally don't support these qualifiers on return type but some people think they do good job with such marks).
回答3:
In which all situations does the -Wextra flag emit uneccessary warnings?
What is your definition of unnecessary? You can consult the manual (this is for 4.9.2) to see exactly what the warning flags do. Then you can decide for yourself whether or not it's right for your code base.
Is it possible to stop the -Wextra flag from enabling the other flags that cause GCC from emitting these types of warnings?
Stick -Wno-
in front of a warning in order to disable it. Not all warnings have a warning flag, which means you probably have to stick with it. You can also generally find more information by browsing their bugtracker by searching for certain warning flags and seeing if any discussions exist. If it's not in the documentation, it might be there. The developers might also express rationale for why things are the way they are.
In order to address the comment you linked to in the comments,
...or warnings about missing field initializers (when you're intentionally initializing a structure with { 0 }, making the compiler zero-initialize everything else automagically).
This argument is moot because it's already been fixed. For example, the following code produces no missing initializer fields warning:
typedef struct { int a; int b; } S;
int main()
{
S s = { 0 };
}
回答4:
It's very simple;
A useless warning is one that never points out an actual bug.
Of course this is undecidable, it's impossible to know beforehand if a particular warning will ever 'save the bacon'.
All GCC warnings have at sometime or other pointed out real bugs, so the general theme with the GCC messages are that -Wall warnings are likely to point at errors and are easy to suppress if they don't. So this plays well with -Werror.
The -Wextra messages, OTOH point at real errors less often or may be point out constructs that are common practice in some older code or are just difficult to change to an alternative way of expressing the code. So sometimes they may indeed be "too verbose".
For new code you will normally want -Wextra on.
For old code it should be turned on if it's not "too verbose".
回答5:
There are basically three types of warnings, and GCC is not very good about grouping them or making this clear:
Warnings that indicate something formally invalid at the source level that should not even compile, but that's allowed for whatever reason (usually compatibility with legacy code). These are mandated by the language standard.
Warnings indicating that your program will necessarily invoke undefined behavior if it reaches the point in the code where the warning occurs. Your program could still be valid if the code is unreachable, and in fact this will likely occur with things like:
int i = 1; if (INT_MAX > 0x7fffffff) <<= 31;
Warnings that are purely heuristic, and do not by themselves indicate any programming error or invalidity of your program, where the compiler is simply warning you that you may have intended something different from what you wrote.
-Wextra
turns on a lot of "type 3" warnings.
Generally everyone agrees types 1 and 2 are valuable, but as mentioned above, even type 2 can have false positives. Type 3 generally has lots of false positives; some of them can be suppressed with harmless changes to the code, while others require actually making your code worse (or turning off the warning locally) to avoid them.
Here's where people will disagree. To some programmers, you just turn on -Wall -Wextra
and locally work around or disable warnings where false positives turn up. Unless you do that, though, false positives create a lot of noise and potentially lower the signal to noise ratio, causing you not to notice the more-serious warnings by getting you used to seeing warnings when you compile.
回答6:
There are (at least) two camps of C programmers: those that think the compiler may sometimes know better, and those that think who is the compiler to tell me how to write my code, after all, I know what I'd doing.
Camp 1 enables warnings as much as they can, use lint and other code checkers to even get more hints about questionable or potentially broken code.
Camp 2 doesn't like their sloppiness being pointed out all the time by a machine, let alone spend extra effort fixing what they think is perfect as-is.
Camp 1 is sought by the industry, because they produce less buggy code, less defects, less customer bug reports. If you're programming launch vehicles, satellite equipment, anything that needs safety, controls really expensive equipment, this camp's mindset is what is needed.
Camp 2 obviously gets away far too often and the general software quality of many applications you use (on your computer, smart phone, appliance, ...) is an indication of this.
What camp do you want to belong to? The disadvantages of -Wextra
depend on this answer. One man's disadvantage is another man's advantage.
来源:https://stackoverflow.com/questions/28381716/disadvantages-of-using-the-wextra-flag-when-compiling-in-gcc