#007 – Warnings and error levels. Make the compiler your ally

When the compiler finds a problem in your source code, it emits a diagnostic message.

Some diagnostics stop the build immediately. Others are warnings: the compiler suspects something is wrong, but it can still produce an executable. Treating those warnings seriously is one of the simplest ways to improve your C++ code quality.

Three things to take away:

  • A compiler error prevents compilation from continuing.
  • A compiler warning reports suspicious code that still compiles.
  • Raising warning levels helps catch bugs before the program runs.

The standard does not define warning style

When the compiler encounters an issue it will emit a diagnostic message or diagnostic for short.

The C++ standard does not define how diagnostic messages should be categorized, worded, or how those issues should affect the compilation of the program. That means GCC, Clang, and MSVC may report different messages for similar problems.

However, compilers have adopted the following convention:

  • A diagnostic/compiler error causes the compiler to stop compilation because the error is serious
  • A diagnostic warning is an issue with the source code but compilation proceeds undisturbed

Increase warning levels

In the spirit of building robust programs, it’s good to increase the sensitivity for warning levels. This provides extra diagnostics information which is helpful during debugging.

Most compilers allow you to raise the warning level.

With GCC or Clang, common warning flags include:

-Wall
-Wextra
-Wconversion
-Wsign-conversion

These enable additional diagnostics beyond the default settings.

For example, -Wconversion warns about implicit conversions that may change a value, and -Wsign-conversion warns about conversions between signed and unsigned integer types.

A typical beginner-friendly command might look like this:

g++ -Wall -Wextra -Wconversion -Wsign-conversion main.cpp -o main

This makes the compiler more strict about questionable code.

That strictness is useful. It catches mistakes early, while the program is still small and easy to reason about

Adding warnings in VSCode

  1. Open the tasks.json file
  2. Find args array

A simplified version might look like this:

"args": [
    "-g",
    "${file}",
    "-o",
    "${fileDirname}/${fileBasenameNoExtension}"
]
  1. Locate the line ${file} within that section.
  2. Above the ${file} line, add new lines containing the following commands (one per line). This enables more warnings
"-Wall",
"-Weffc++",
"-Wextra",
"-Wconversion",
"-Wsign-conversion",

The final result should look like this:

"args": [
    "-g",
    "-Wall",
    "-Wextra",
    "-Wconversion",
    "-Wsign-conversion",
    "${file}",
    "-o",
    "${fileDirname}/${fileBasenameNoExtension}"
]

Treating warnings as errors

At the beginning, I mentioned that warnings do not cause compilation to fail. We can enforce these warnings such that a warning will result in an unsuccessful compilation.

This is good programming practice.

In the tasks.json file, add the following flags before ${file}, one per line:

"-Werror",

This tells the compiler to treat warnings as errors. If the compiler emits a warning, the build fails.

A good rule is:

Use high warning levels everywhere

In Conclusion

A program can compile cleanly and still be wrong. Warnings help close that gap by catching suspicious patterns before the program runs.

Compiler warnings are early bug reports.

Errors tell you when the compiler cannot translate your program. Warnings tell you when the compiler can translate it, but something deserves attention. Raise your warning levels, read the diagnostics carefully, and keep your builds clean