I am a fan of warnings. By highlighting dangerous or ambiguous areas of our code, warnings provide valuable insight and advice for keeping your programs tidy. Since I like warnings so much, I try to turn on as many of them as possible, while sifting out any annoying warnings like
Many developers are familiar with some of the common warning flags like
-Wall, but I'd like to give you a quick refresher on the following flags:
Many programmers know about the
-Wall flag already. Given my inclusion of other flags such as
-Weverything, I hope it is clear that
-Wall does not actually ALL the warning flags. Regardless, enabling
-Wall in your code will provide you with a decent amount of warning coverage and boost your program's resiliency.
According to the GCC manual, the
-Wall flag "enables all the warnings about constructions that some users consider questionable, and that are easy to avoid (or modify to prevent the warning), even in conjunction with macros. This also enables some language-specific warnings described in C++ Dialect Options and Objective-C and Objective-C++ Dialect Options."
Here is a full list of the 48 flags enabled by
-Wcatch-value(C++ and Objective-C++ only)
-Wduplicate-decl-specifier(C and Objective-C only)
-Wenum-compare(in C/ObjC; this is on by default in C++)
-Wimplicit(C and Objective-C only)
-Wimplicit-int(C and Objective-C only)
-Wimplicit-function-declaration(C and Objective-C only)
-Winit-self(only for C++)
-Wmain(only for C/ObjC and unless
-Wmisleading-indentation(only for C/C++)
-Wmissing-braces(only for C/ObjC)
-Wnarrowing(only for C++)
-Wsign-compare(only in C++)
After seeing the list of warnings provided by
-Wall, you may be wondering why you need any others.
-Wextra provides warnings that are helpful but much more pedantic, covering topics such as empty function bodies, unused parameters, and sign mismatches in comparisons. These warnings are often viewed as a nuisance, but they also help eliminate bad coding styles and point out potential bugs (maybe you did intend to use that parameter).
Here's the full list of flags enabled by
-Wshift-negative-value(in C++03 and in C99 and newer)
-Wextra also enables warnings for the following conditions:
- A pointer is compared against integer zero with <, data-preserve-html-node="true" <=, data-preserve-html-node="true" >, or >=.
- (C++ only) An enumerator and a non-enumerator both appear in a conditional expression.
- (C++ only) Ambiguous virtual bases.
- (C++ only) Subscripting an array that has been declared register.
- (C++ only) Taking the address of a variable that has been declared register.
- (C++ only) A base class is not initialized in the copy constructor of a derived class.
-Wpedantic takes our warnings even further. The
-pedantic set contains "all the warnings demanded by strict ISO C and ISO C++; reject all programs that use forbidden extensions, and some other programs that do not follow ISO C and ISO C++. For ISO C, follows the version of the ISO C standard specified by any -std option used."
-Wpedantic also rejects certain GNU extensions and C/C++ features that are not ISO-compliant.
The GNU manual notes that many will try to use
-Wpedantic to check for ISO C conformance, but keep in mind:
-Wpedantic only checks for non-ISO practices for which diagnostics are required or have already been added. Even so,
-Wpedantic is a useful flag if you are aiming for ISO C/C++ conformance. Primarily, I enable this flag temporarily to find areas where my programs can be improved.
Clang helpfully provides a flag called
-Weverything flag really will enable all warnings. Literally every warning in clang.
-Weverything can be an eye-opening experience, even for those who religiously squash warnings. I often turn on
-Weverything temporarily to review any of the less-common warnings and see what's worth fixing in my code base. I often discover new warning flags this way.
You will be annoyed at new warnings popping up in your CI system (and potentially causing build failures) every time there's a toolchain update. I don't recommend using this flag in your production build rules.
Turning On Specific Warnings
-Wextra provide a very comprehensive set of warnings, but many developers are picky about the warnings they want to deal with in their projects.
Rather than cause strife by turning on more warnings than your team can tolerate, I recommend an alternative approach: start with
-Wall (something most developers can stomach) and specifically enable warnings that will benefit your team.
You can enable specific warnings by combining the
-W prefix with the warning name, such as:
This approach allows you to enable valuable warnings in your project without a flood of other minor warnings that come with enabling something like
Turning Off Specific Warnings
Similar to using the
-W prefix with a warning name to enable a warning, you can use the
-Wno- prefix to disable a warning explicitly. For example:
Disabling warnings explicitly can be useful in cases where the warning behavior cannot be suppressed and is intentional.
Clang: Locally Disabling Warnings
Clang provides even further granular control over disabling warnings using the
diagnostic pragma. You can disable warnings over a small region of code:
#pragma clang diagnostic push #pragma clang diagnostic ignored "-Wconversion" serverAddress->ss_family = host->h_addrtype; #pragma clang diagnostic pop
I often use this method for including external libraries and headers that have warnings which I won't be fixing.
Some people struggle even with enabling
-Wall, as some of the constructions that cause warnings can be hard to avoid or suppress. At a minimum, we recommend
Suck it up, it's better to fix these warnings.
-Werroris not your friend
- GNU Warning Options - details on warnings included with
- Fucking Clang Warnings - a better overview of clang warnings
- Don't put
-Weverythingin your build flags
- Added some clarifying notes about -Weverything