In the last post I wrote about how to change our code to avoid getting compiler warnings. Sometimes that is not a feasible approach and we need to tell your compiler to simply shut up.
Tell the compiler which warnings interest you
There are different ways to get a clean compiler output with no warnings. Clearly, getting rid of them by writing code that is clear even for the compiler is the best option. However, there are options how you can tell your compiler which warnings interest you and which don’t.
Every compiler I know of provides means to select which warnings we want to see. We can turn on different warning levels or groups of warnings, and sometimes we can assign single warnings to a different warning level. Usually those settings are provided as command line parameters or settings in the IDE. That means you can have a single point – preferably your build script – where you apply these settings.
Which warning flags should we use? That depends a bit on the compiler, since different compilers emit different warnings, and some warnings may be nonsense or buggy. Some warnings may seem too pedantic for your taste or coding style, though I have yet to see a warning that does not have some merit. Therefore I usually strive to see all warnings I can get and fix them. Common flags for maximum warnings are `Wall`, `Wpedantic`, `Wextra` (many compiler flags regarding warnings start with `W`).
Aim for the highest warning level you can get.
If you are just starting to introduce the “no warnings” policy in your project you may get hundreds or even thousands of warnings if you switch on all warnings. To get started you may want to start with a lower warning level. Fix the most severe warnings first and gradually dial up the warning level.
If you tend to have lazy moments like me or have colleagues that are not sold to the concept of no having no warnings at all, it can be a bit hard to stay at zero warnings. Someone might be tempted to check in code that contains a warning. After all, it’s not an error, the code compiles and will probably work as intended. That way the pile of warnings creeps back in one by one.
To avoid that you can enforce the “no warnings” policy by explicitly turning warnings into errors. That way warnings can not be ignored because the build fails. This can usually be done for single warnings, but also for all warnings at once. The corresponding flags are `-Werror` for Clang and GCC and `/WX` for MSVC.
Consider to turn all warnings into errors.
Compilers usually provide special `#pragma`s to turn specific warnings on and off in code. Those `#pragma`s should be considered a workaround, since they have some problems:
- Turning a warning off with a `#pragma` silences the compiler for the rest of the compilation unit. If you want to turn off the warning only for a single occurrence, you have to turn it on explicitly after the line of code in question. Putting such a `#pragma` in a header and not turning the warning on again will silence the compiler for every source that includes the header and for ever header included after the `#pragma`
- `#pragma`s for warnings are not portable. The identifiers for a given warning vary between compilers as well as the format for the `#pragma`. Compilers sometimes emit warnings about unknown `#pragma`s – and you’ll definitely not want to write a GCC warning `#pragma` that it should ignore those MSVC warning `#pragma`s. Wrapping them in `#ifdefs` is ugly at best.
Avoid warning #pragmas where possible
There may be times you don’t get around writing a `#pragma`. Examples can be headers of third party libraries that you can’t change but where your compiler complains. Another example I remember is an embedded DSL I once wrote – it used operator overloading in a unusual way that defied C++’s builtin operator precedence.
The compiler helpfully warned that some additional parentheses might make the intent clearer. It could have been right, had the operators been applied to numbers. To leave the DSL code readable, I had to silence the warning without touching the code, so I turned it off via a `#pragma` accompanied with an explaining comment.
You can tell the compiler which warnings you are interested in in a very detailed fashion, using command line arguments and, if necessary,`#pragma`s. Prefer to be as strict as possible, don’t add too many special cases. That means only sparingly use `#pragma`s, and also per file deviations from your usual command line arguments.