close menu

Warnings are not errors


31 May 2019


This article was originally published on my Medium page .

It is not uncommon to see software projects which enforce compilation with -Werror (or equivalent compiler flags). The intention behind this practice is to make warnings (which are obviously undesirable) explode in a programmer's face so that they are dealt with as soon as possible.

The justification here being that, in a particular piece of software, the tooling will make warnings impossible to ignore, and the software will be written better by product of force. This is a powerful idea. A machine can exercise its power to make sure there is no cruft in the code that powers it. Even something as uninteresting as an unused variable will prevent your code from compiling. Warnings cry for attention, and by promoting them to errors, you give them centre-stage.

This is fantastic for code that is going to be deployed to production (however that is defined). By forcibly minimizing declarations, you reduce binary size. By forcibly avoiding undefined or dangerous behaviour, you ensure deterministic behaviour. By forcing opinionated usage of particular language features, the compiler will make smarter optimizations.

But this same thing is dramatically worse for code that is in development. Treating warnings as errors means that if halfway through feature development you decide you want to compile your code or run some tests to make sure you haven't broken anything — well my friend, you are out of luck. Strip out those half-baked features and unused variables, because incremental feature development doesn't really exist for you.

Let's say you have a project that uses a class called FancyAPI extensively, and the maintainer of that software decides to deprecate it.

@Deprecated("FancyAPI2 does this better!")
class FancyAPI { … }

Marking a class as deprecated is essential for clients to eventually migrate to better code; developers of client code will note the warnings, and refactor accordingly. Yay!

If the changes are too big to make immediately though, treating these warnings as errors completely blocks development until it can be fixed. If you're working in a team, they get blocked too! This is not good!

No one wants to be blocked, so the quick-fix is usually to suppress the deprecation warning and keep chugging along happily.

@Suppress("DEPRECATION")
class FancyAPIConsumerWidgetFactoryBuilder { … }

This is not good! Now you're working with deprecated code, one of the very things you were trying to avoid, and you're going to forget about it! If you treat warnings as errors, then I'd posit that the goal of software development strays from writing good code to focusing on the erasure of warnings. Yikes.


Please leave warnings as warnings — your compiler will helpfully nag you about this stuff but it won't get in your way. You'll write better software for it too!