TGViewer
C++ - Reddit C++ - Reddit @r_cpp · 230 subscribers
Post #25787 3
No, -Wall -Werror Does Not Guarantee Detection of Conditionally Uninitialized Local Variables

There seems to be a misconception or lack of clarity about the usage of the compilation flags -Wall and -Werror and their ability to detect uninitialized stack variables. It depends. In this post, I will try to explore this further and explain when and how it is detected, and where it may not detect an uninitialized local variable and hence requires more caution while dealing with it. Consider the following code:

int main()
{
int value;
return value;
}

Compile this code as follows:

~/cpp_26_uninitialised$ g++ -std=c++23 -Wall -Werror test.cpp -o test
test.cpp: In function ‘int main()’:
test.cpp:4:12: error: ‘value’ is used uninitialized [-Werror=uninitialized]
4 | return value;
| ^~~~~
test.cpp:3:9: note: ‘value’ was declared here
3 | int value;
| ^~~~~
cc1plus: all warnings being treated as errors

So, with the use of the two compilation flags, `-Wall` and `-Werror`, the compilation fails, and you can then take corrective measures to address the uninitialized variable in the code.

Strictly speaking, -Wall enables the -Wuninitialized warning, and -Werror turns that warning into an error. However, *this is true only when the variable is uninitialized on every path to its use*, as `value` is here. It doesn't reliably work for a variable that is initialized on some paths and left uninitialized on others. Have a look at the following code:

// config_timeout_warning_test.cpp
#include <charconv>
#include <cstdio>
#include <string_view>

constexpr int default_timeout_ms = 1000;

// Reads "timeout_ms=<number>" from a device configuration line.
// The bug: when the key is missing, timeout_ms is never assigned.
[[gnu::noinline]] int read_timeout_ms(std::string_view config)
{
int timeout_ms;

constexpr std::string_view key = "timeout_ms=";

if (const auto pos = config.find(key); pos != std::string_view::npos)
{
const char* first = config.data() + pos + key.size();

const char* last = config.data() + config.size();

std::from_chars(first, last, timeout_ms);
}

return timeout_ms;
}

void open_device(const char* name, std::string_view config)
{
const int timeout_ms = read_timeout_ms(config);

if (timeout_ms <= 0)
{
std::printf("%-7s no timeout configured, using default %d ms\n", name, default_timeout_ms);
}
else
{
std::printf("%-7s timeout %d ms\n", name, timeout_ms);
}
}

int main()
{
// The empty configuration does not contain "timeout_ms=".
// Therefore, timeout_ms is returned without being initialized.
open_device("logger", "");

return 0;
}

Compile the code as follows:

~/cpp_26_uninitialised$ g++ -std=c++23 -O0 -g -Wall -Werror config_timeout_warning_test.cpp -o timeout_warning_test

The compilation succeeds without a single warning. Run Valgrind on it:

~/cpp_26_uninitialised$ valgrind --track-origins=yes ./timeout_warning_test
==2896379== Memcheck, a memory error detector
==2896379== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==2896379== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==2896379== Command: ./timeout_warning_test
==2896379==
==2896379== Conditional jump or move depends on uninitialised value(s)
==2896379== at 0x401268: open_device(char const*, std::basic_string_view<char, std::char_traits<char> >) (config_timeout_warning_test.cpp:31)
==2896379== by 0x4012D3: main (config_timeout_warning_test.cpp:45)
==2896379== Uninitialised value was created by a stack allocation
==2896379== at 0x401166: read_timeout_ms(std::basic_string_view<char, std::char_traits<char> >) (config_timeout_warning_test.cpp:10)
More from @r_cpp
  1. Oct 6, 2026WasmBolt — The LLVM Project in your browser https://anutosh21.github.io/WasmBolt/ https://…
  2. Oct 6, 2026How I speed up my overall build times by 4x and incremental builds by 9x for test builds *…
  3. Oct 6, 2026Why do people on Windows mostly choose Visual Studio? https://redd.it/1weku08 @r_cpp
  4. Oct 6, 2026Jonas Persson: Making every byte count https://youtu.be/GbwrztrY4kc https://redd.it/1wf1l3…
  5. Oct 6, 2026It annoys me that coroutines are described as "functions that can be suspended" Any functi…
  6. Oct 6, 2026==2896379== logger no timeout configured, using default 1000 ms ==2896379== ==2896379== HE…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →