
不初始化的 int 变量值是随机的
在 C++ 里,局部 int 变量如果不显式初始化,它的值就是未定义的——不是 0,不是 -1,也不是“空”,而是内存里上一个使用者留下的任意比特组合。你每次运行可能得到不同结果,调试时有时碰巧是 0,就误以为“默认是 0”,其实纯属运气。
常见错误现象:
程序偶尔崩溃、逻辑错乱、CI 上测试通过但本地复现失败、用 AddressSanitizer 报 use-of-uninitialized-value。
- 全局/静态
int确实会零初始化(这是 C++ 标准保证的),但局部变量完全不享受这个待遇 -
int x;和int x = 0;在栈上生成的汇编指令完全不同,后者明确写入 0 - 启用
-Wall -Wuninitialized(GCC/Clang)能捕获大部分情况,但仍有漏网之鱼(比如条件分支中某条路径没赋值)
什么时候会被自动初始化为 0
只有满足“静态存储期”的 int 才 guaranteed zero-initialized:全局变量、static 局部变量、static 成员变量、constexpr 初始化的变量(如果表达式求值结果确定)。
使用场景:
计数器缓存、单例内部状态、需要跨函数调用保持初值的变量。
立即学习“C++免费学习笔记(深入)”;
-
int global_x;→ 值为 0 -
void f() { static int s_x; }→ 第一次进入时为 0,之后保持上次值 -
int local_x;(在函数内)→ 绝对不保证为 0 -
std::vector<int> v(5);</int>→ 元素全为 0(因为int()是 0),但std::vector<int> v; v.resize(5);</int>后元素是未初始化的
int{} 和 int() 都是安全的零初始化
统一用花括号或圆括号初始化,能避免遗漏,也明确表达意图。这两种写法在 C++11 起语义一致,都触发值初始化(value-initialization),对内置类型即为零初始化。
性能影响几乎为零:现代编译器对 int x{}; 和 int x = 0; 生成的机器码完全一样,无额外开销。
- 推荐写法:
int x{};(更现代,且和类类型初始化风格统一) - 等价写法:
int x = int{};或int x();(注意后者是函数声明!别写成这样) - 绝对避开:
int x;(局部作用域下) - 结构体中成员也适用:
struct S { int a{}; };→a总是 0
结构体/类里 int 成员不初始化照样危险
哪怕整个对象用了 new 或 malloc,只要没走构造函数或没显式初始化列表,int 成员仍是未定义值。尤其容易在自定义构造函数里漏掉某个成员。
常见坑:
写了构造函数但忘了初始化列表;用 memset(this, 0, sizeof(*this)); 试图“清零”,但对含虚函数或非 POD 类型是未定义行为;聚合初始化时只填了前几个字段。
-
struct S { int a, b; S() {} };→a和b都未定义 -
S s{};(聚合初始化)→a和b都是 0 -
S* p = new S;→ 未定义;S* p = new S{};→ 安全 - 含
std::string成员的类,即使int没初始化,也可能因字符串内部状态混乱导致 crash,掩盖真正问题
C++ 不会给局部 int 任何默认值,这点和 Java 或 Python 完全不同。最稳妥的做法,就是养成写 {} 的习惯——多敲两个字符,省去半天查野值的时间。










