Other than -Wall, what other warnings have people found useful?
-
Related: *[What are the useful GCC flags for C?](https://stackoverflow.com/questions/3375697/what-are-the-useful-gcc-flags-for-c)* – Peter Mortensen Oct 27 '22 at 23:37
15 Answers
I routinely use:
gcc -m64 -std=c99 -pedantic -Wall -Wshadow -Wpointer-arith -Wcast-qual \
-Wstrict-prototypes -Wmissing-prototypes
This set catches a lot for people unused to it (people whose code I get to compile with those flags for the first time); it seldom gives me a problem (though -Wcast-qual is occasionally a nuisance).

- 30,738
- 21
- 105
- 131

- 730,956
- 141
- 904
- 1,278
-
1These days, I find I have to add '`-Wdeclaration-after-statement`' in order to detect code that MSVC (which is still basically a C89 compiler) won't handle. 'Tis a nuisance. Adding '`-Wextra`' can spot some other problems too. – Jonathan Leffler Jul 06 '10 at 14:00
-
2Also, it is a good idea to add `-O3` or something similar; there are warnings that are only generated when the code is optimized. – Jonathan Leffler Mar 05 '12 at 06:26
-
3according to gcc doc, -O2 is the best to spot warnings. I'm not sure if -O3 imply -O2 or allow more warnings to be generated. – Offirmo Aug 21 '12 at 12:55
-
3
-
1Using both `-m32` _and_ `-m64` (in separate runs, of course) provides better protection from various bugs in the way you use `printf()` and `scaf()` conversion specifications. – Jonathan Leffler Oct 17 '14 at 11:56
As of 2011-09-01, with GCC version 4.6.1
My current "development" alias
gcc -std=c89 -pedantic -Wall \
-Wno-missing-braces -Wextra -Wno-missing-field-initializers \
-Wformat=2 -Wswitch-default -Wswitch-enum -Wcast-align \
-Wpointer-arith -Wbad-function-cast -Wstrict-overflow=5 \
-Wstrict-prototypes -Winline -Wundef -Wnested-externs \
-Wcast-qual -Wshadow -Wunreachable-code -Wlogical-op \
-Wfloat-equal -Wstrict-aliasing=2 -Wredundant-decls \
-Wold-style-definition -Werror \
-ggdb3 \
-O0 \
-fno-omit-frame-pointer -ffloat-store \
-fno-common -fstrict-aliasing \
-lm
The "release" alias
gcc -std=c89 -pedantic -O3 -DNDEBUG -lm
As of 2009-11-03
"development" alias
gcc -Wall -Wextra -Wformat=2 -Wswitch-default -Wcast-align \
-Wpointer-arith -Wbad-function-cast -Wstrict-prototypes \
-Winline -Wundef -Wnested-externs -Wcast-qual -Wshadow \
-Wwrite-strings -Wconversion -Wunreachable-code \
-Wstrict-aliasing=2 \
-ffloat-store -fno-common -fstrict-aliasing \
-lm -std=c89 -pedantic -O0 -ggdb3 -pg --coverage
"release" alias
gcc -lm -std=c89 -pedantic -O3 -DNDEBUG --combine \
-fwhole-program -funroll-loops

- 30,738
- 21
- 105
- 131

- 106,608
- 13
- 126
- 198
-
1
-
5Note that `-Wstrict-aliasing=2` actually lowers the warning level of `-Wstrict-aliasing=3` implied by `-Wall`, at least with a recent version of gcc. – nwellnhof Jan 31 '15 at 14:20
-
@nwellnhof that's the crux of custom warning settings, they rot over time... – yugr Jan 08 '22 at 13:48
-
`-Wunreachable-code` has been [listed as a dummy switch since GCC 4.6](https://github.com/Barro/compiler-warnings/blob/master/gcc/warnings-gcc-4.6.txt#L136) (GCC 4.6.0 [was released](https://gcc.gnu.org/releases.html) on 2011-03-25). [An answer](https://stackoverflow.com/questions/14591778/using-g-results-in-warning-will-never-be-executed/14591938#14591938) claims *"-Wunreachable-code has always been broken "*. – Peter Mortensen Oct 27 '22 at 20:21
-
`-combine` was [removed in GCC 4.6.0](https://gcc.gnu.org/gcc-4.6/changes.html) (released 2011-03-25): *"The C-only intermodule optimization framework (IMA, enabled by -combine) has been removed in favor of the new generic link-time optimization framework (LTO) introduced in GCC 4.5.0."*. The last version was [4.5.4](https://gcc.gnu.org/onlinedocs/gcc-4.5.4/gcc/Overall-Options.html#index-combine-82). It is listed as `-combine`, not `--combine` – Peter Mortensen Oct 28 '22 at 19:42
I started out with C++, so when I made the switch to learning C I made sure to be extra-anal:
- -fmessage-length=0
- -ansi -pedantic -std=c99
- -Werror
- -Wall
- -Wextra
- -Wwrite-strings
- -Winit-self
- -Wcast-align
- -Wcast-qual
- -Wpointer-arith
- -Wstrict-aliasing
- -Wformat=2
- -Wmissing-declarations
- -Wmissing-include-dirs
- -Wno-unused-parameter
- -Wuninitialized
- -Wold-style-definition
- -Wstrict-prototypes
- -Wmissing-prototypes

- 30,738
- 21
- 105
- 131

- 10,689
- 4
- 41
- 50
-
6Can you use -ansi -pedantic -std=c99 at the same time? Is not -ansi approximately the same thing as c89? and if so how does that work with the c99 flag? – Johan Oct 26 '09 at 05:13
-
2@Johan - you can, and it's not actually necessary, as I've found out more recently. -ansi implies -std=
, so really you could just say -std=c99 -pedantic and get exactly the same effect. I do tend to use it anyways, just for the documentation effect. I feel that it reads, "This code is ANSI-standard (pedantic!), using standard C99." Immediately afterwards usually comes -Wno-long-long or similar... any exceptions to the ANSI standard. – Tom Oct 27 '09 at 02:27 -
1Aren't you missing `-pedantic-errors`? It's not equal to `-Werror=pedantic`. – x-yuri Jul 26 '21 at 17:00
-
1As mentioned in comments to other answer, `-Wstrict-aliasing` is now part of `-Wall`. – yugr Jan 08 '22 at 13:48
I like -Werror. It keeps the code warning free.

- 30,738
- 21
- 105
- 131

- 63,317
- 21
- 138
- 197
-
21Without -Werror all other warning options are pointless. Treating warnings as errors is pretty much the only way to ensure warnings get resolved. If they're just warnings a developer may decide to leave one in because he's sure it's invalid. It may even be true, but the next developer won't fix the warnings he introduced because he didn't see it between all the others, or because it's just one more warning. – Kristof Provost Jul 17 '09 at 20:51
-
-
7I disagree with Kristof, because many times, I'd rather just get a working copy compiled first and _then_ address the errors. – Yktula Apr 21 '10 at 20:14
-
9I understand why that is tempting, but when/if you have a working copy you will be more likely to leave it as it is because "it works". This risk is even higher in a corporate environment, where you'll have to convince your boss to leave you some time to fix the warnings. – JesperE Apr 26 '10 at 06:44
-
1The problem with `-Werror` is, that you cannot used the preprocessor construct `#warning` any longer, as those become errors, too and thus your code will not compile at all any longer. Keeping warning as warnings is okay, just make sure your final code is free of warnings prior to releasing any products. – Mecki Nov 08 '13 at 17:44
-
2I consider getting rid of `#warning` a good side effect of using `-Werror`. – JesperE Nov 11 '13 at 19:36
-
5if you work on Open Source stuff don't use `-Werror` by default in your builds it annoys packagers who are using different compiler versions from you since the warnings change with compiler version sometimes code that is warning free for you will have a warning for someone else and then they have to dig into your build system to turn it off. – Spudd86 Dec 15 '13 at 16:46
-
1Yes, that's a nuisance. However, in many cases it is easier to dig into the sources and fix the warning. One typical case I've seen many times is missing header files coming from gcc getting stricter and stricter about not sucking in header files as a side effect (getting
when including – JesperE Dec 16 '13 at 08:14, for example). These are trivial to fix, even for inexperienced developers. -
2Forcing packagers to modify your code to get it to build without warnings on their system is asking for bugs like the Debian SSL bug[1]. There are useful reasons to allow code to compile with warnings, and if your developers are too lazy to fix warnings before work is checked in then you surely have bigger quality control issues than -Werror can fix. [1] https://www.schneier.com/blog/archives/2008/05/random_number_b.html – pavon Aug 24 '16 at 16:04
Get the manual for the GCC version you use, find all warning options available, and then deactivate only those for which you have a compelling reason to do so. (For example, non-modifiable third-party headers that would give you lots of warnings otherwise.) Document those reasons. (In the Makefile or wherever you set those options.) Review the settings at regular intervalls, and whenever you upgrade your compiler.
The compiler is your friend. Warnings are your friend. Give the compiler as much chance to tell you of potential problems as possible.

- 67,862
- 21
- 134
- 209
-
3FYI, the manual does not provide a single comprehensive list of warnings. However, you can find such lists [here](https://github.com/barro/compiler-warnings), along with the tools used to generate them. – Kyle Strand Feb 28 '16 at 18:50
I also use:
To catch those nasty bugs that may occur if I write code that relies on the overflow behaviour of integers.
And:
Which enables some options that are nice to have as well. Most are for C++ though.

- 30,738
- 21
- 105
- 131

- 83,631
- 31
- 151
- 221
I usually compile with "-W -Wall -ansi -pedantic".
This helps ensure maximum quality and portability of the code.

- 30,738
- 21
- 105
- 131

- 87,561
- 32
- 179
- 238
-pedantic -Wall -Wextra -Wno-write-strings -Wno-unused-parameter
For "Hurt me plenty" mode, I leave away the -Wno...
I like to have my code warning free, especially with C++. While C compiler warnings can often be ignored, many C++ warnings show fundamental defects in the source code.

- 30,738
- 21
- 105
- 131

- 10,038
- 6
- 38
- 54
-
3Because the toolchain is at liberty to put string literals into read-only memory. – DevSolar Jul 05 '10 at 19:38
-
3Why -Wno-unused-parameter? Very seldomly it points to real problems (and the "very seldomly" the exact danger with disabling it: unprobable bugs are the worst to detect). E.g., if may trigger on `Foo(int dndu, int dndv) : dndu_(dndu), dndv_(dndu) {}` -> relatively hard to spot. If you are annoyed by that warning, you should simply outcomment the parameter `foo (int /*q*/)`, this also increases readability of your code. – Sebastian Mach May 08 '11 at 11:07
-
During refactoring I've sometimes shadowed the parameter by mistake with a local, it helps catch that too – paulm Jul 08 '16 at 13:47
Right now I use:
-Wall -W -Wextra -Wconversion -Wshadow -Wcast-qual -Wwrite-strings -Werror
I took that list mostly from the book "An Introduction to GCC" (by rms) and then some from Ulrich Drepper's recommendation about defensive programming (slides for Defensive Programming).
But I don't have any science behind my list. It just felt like a good list.
Note: I don't like those pedantic flags though...
Note: I think that -W and -Wextra are more or less the same thing.

- 30,738
- 21
- 105
- 131

- 20,067
- 28
- 92
- 110
-
2Afer using -Wconversion, and spending a couple of hours testing various data types in my code and re-building, I researched -Wconversion and would not recommend using it in general. The problem being it generates warnings about code such as: char a = 5; char b = a - 1; This is using gcc 4.3.2 (Debian 4.3.2.-1.1) – James Morris Oct 25 '09 at 19:27
-
1-Wconversion warnings can be eliminated by (for example in above comment): char a = 5; char b = (char)(a - 1); note brackets. – James Morris Oct 25 '09 at 19:40
I generally just use
gcc -Wall -W -Wunused-parameter -Wmissing-declarations -Wstrict-prototypes -Wmissing-prototypes -Wsign-compare -Wconversion -Wshadow -Wcast-align -Wparentheses -Wsequence-point -Wdeclaration-after-statement -Wundef -Wpointer-arith -Wnested-externs -Wredundant-decls -Werror -Wdisabled-optimization -pedantic -funit-at-a-time -o
With references:
- -Wall
- -W
- -Wunused-parameter
- -Wmissing-declarations
- -Wstrict-prototypes
- -Wmissing-prototypes
- -Wsign-compare
- -Wconversion
- -Wshadow
- -Wcast-align
- -Wparentheses
- -Wsequence-point
- -Wdeclaration-after-statement
- -Wundef
- -Wpointer-arith
- -Wnested-externs
- -Wredundant-decls
- -Werror
- -Wdisabled-optimization
- -pedantic
- -funit-at-a-time
- -o

- 30,738
- 21
- 105
- 131

- 1,040
- 7
- 8
It would be the option -pedantic-errors.

- 30,738
- 21
- 105
- 131

- 99,986
- 30
- 138
- 174
-
2@unexist Try installing `clang` (the C compiler of the LLVM project) and then compile with `-Weverything` and you'll see how mach fun compiling can really become (some of the warnings are totally crazy, yet they are technically correct). – Mecki Nov 08 '13 at 17:42
-Wfloat-equal, -Wshadow, and -Wmissing-prototypes.

- 30,738
- 21
- 105
- 131

- 19,598
- 4
- 47
- 69
- -Wredundant-decls
- -Wnested-externs
- -Wstrict-prototypes
- -Wextra
- -Werror-implicit-function-declaration
- -Wunused
- -Wno-unused-value
- -Wreturn-type

- 30,738
- 21
- 105
- 131

- 13,986
- 6
- 46
- 47
-
Re *"`-Werror-implicit-function-declaration`"*: Do you mean *"[`-Werror=implicit-function-declaration`](https://stackoverflow.com/questions/9182763/implicit-function-declarations-in-c)"*? – Peter Mortensen Oct 23 '22 at 20:11
-
Or *[`-Wimplicit-function-declaration`](https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wimplicit-function-declaration)* or *[`-Wno-implicit-function-declaration`](https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wno-implicit-function-declaration)*? – Peter Mortensen Oct 23 '22 at 20:13
I use this option:

- 30,738
- 21
- 105
- 131

- 7,249
- 5
- 33
- 54
-
I think `-Werror` is preferred as it will not stop after first error and allow you to fix several errors before restarting the build. – yugr Jan 05 '22 at 08:18