调试变量需确保编译带-g且禁用优化(-o0),gdb用p、lldb用expr查看,display可自动刷新;悬停/监视失效多因符号缺失或优化;cerr比cout更可靠,因其无缓冲。

在调试器里用 print 或 display 命令看变量值
最直接的方式是打断点后,在 GDB 或 LLDB 中输入命令查值。GDB 里用 print var_name(简写 p var_name),LLDB 里同样支持 print var_name,也支持更自然的 expr var_name。
注意变量名必须在当前作用域可见,比如函数参数、局部变量、this 指向的对象成员。如果变量被优化掉了(比如编译时加了 -O2),print 可能报错 No symbol "xxx" in current context —— 这时候得关优化重编译。
- 查看指针指向的内容:用
p *ptr - 查看数组前 5 个元素:用
p arr@5(GDB)或p (int[5])arr(LLDB) - 想持续观察某个变量变化:GDB 用
display var_name,之后每次单步都会自动打印
用 std::cout 或 printf 临时输出
适合快速验证、无法连调试器(如嵌入式环境、CI 日志中)或变量生命周期短到打断点来不及看的情况。
注意类型匹配问题:printf 对 std::string、std::vector 等不友好,强行传会崩溃;std::cout 更安全但需包含 <iostream></iostream>,且对自定义类型要重载 operator。
- 基本类型直接输出:
std::cout - 避免线上残留:用预处理器包裹,比如
#ifdef DEBUG ... #endif - 结构体/类建议单独写一个
debug_print()成员函数,而不是到处塞cout
IDE 调试界面里鼠标悬停或监视窗口失效怎么办
Clion、VS2022、VS Code + C++ extension 都支持悬停看值,但常见失效原因不是功能坏了,而是符号信息没加载全或变量被优化。
检查三件事:gdb/lldb 是否正确配置、编译是否带 -g、CMake 或构建系统有没有意外启用 -O2。Clion 默认用 LLDB,macOS 上有时需要手动指定 lldb --version 可用;Windows 下 VS2022 对 /Zi 和 /ZI 的兼容性也有差异。
- 悬停显示
<optimized out></optimized>→ 关掉编译优化,CMake 中设CMAKE_BUILD_TYPE=Debug - 监视窗口输
this->member报错 → 尝试先展开左侧变量树找到该成员,再拖进去 - 字符串只显示前几个字符 → 在 Clion 的 Settings → Build → Debugger → Data Views → C/C++ 中调大 “String length limit”
std::cerr 比 std::cout 更适合调试输出
因为 std::cerr 默认不缓冲,输出立刻刷到终端;而 std::cout 在行缓冲或全缓冲模式下,程序 crash 前的最后几条可能根本看不到。
尤其在排查段错误、死循环或异常退出时,std::cerr 输出大概率比 std::cout 多一两行,这点差异常是定位关键。
- 写法几乎一样:
std::cerr - 配合宏更省事:
#define DEBUG_LOG(x) std::cerr - 注意不要在多线程里无锁混用
std::cerr,否则日志可能乱序或截断
-g 和 -O0 检查清楚,比翻文档更快。C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











