Let’s look at this C++ program:
#include <iostream>
int main() {
int x;
if (x == 0) {
std::cout << "Zero";
}
else {
std::cout << "Not zero";
}
}
When you build it in Debug and in Release mode, then:
-
Debug build prints
Not zero -
Release build prints
Zero
Same code. Same compiler. Different result.
What does it mean?
The bug comes from the undefined behavior of the uninitialized variable x:
int x;
x is declared, but never initialized and immediately used:
if (x == 0)
At this point, the program is reading a variable that has no defined value at all.
Why it happens
Stack memory
When you write:
int x;
on the stack, no initialization happens. The memory might contain:
- leftover values from previous function calls
- debug patterns inserted by the runtime
- basically anything
So x is effectively "whatever bits happened to be in that memory slot”.
Debug vs Release changes memory behavior
This is where things get interesting. Debug runtimes often:
- fill stack memory with known patterns (e.g.
0xCC,0xCD) - keep extra safety checks
- avoid aggressive register optimization
So x is very likely to contain a non-zero pattern, but in Release mode:
- stack memory is not initialized
- registers are heavily optimized
- memory reuse is aggressive
So sometimesx happens to be 0, but sometimes it gets optimized into a register that defaults to zero in that execution path The C++ standard does not say that x is garbage or random or zero. It says that reading an uninitialized variable is undefined behavior what means:
- compiler is allowed to assume it never happens
- optimizations may remove or rewrite logic
- results can differ between builds, machines or even runs
How to fix it?
The simplest fix may be limited to just adding curly braces {} after x - it will zero-initialize it, so that it has a known value (equal to 0) in both types of builds:
#include <iostream>
int main() {
int x {};
if (x == 0) {
std::cout << "Zero";
}
else {
std::cout << "Not zero";
}
}
Now behavior is fully defined and consistent. I also encourage to enable compiler warnings to catch all such places:
-Wall -Wextra -Wuninitialized -Werror
Top comments (0)