1. assert
是什么?
assert
是 C/C++ 标准库提供的一个调试辅助宏,定义在<assert.h>
或<cassert>
。用法:
#include <assert.h> int main() { int x = 5; assert(x > 0); // ✅ 条件成立,继续执行 assert(x < 0); // ❌ 条件不成立,程序中断 return 0; }
工作原理:
assert(expr)
会检查expr
是否为 真:如果为真 → 什么都不做,继续执行。
如果为假 → 向标准错误输出报错信息(表达式、文件名、行号),并调用
abort()
终止程序。
报错例子:
a.out: test.cpp:5: main: Assertion `x < 0' failed.
Aborted (core dumped)
2. NDEBUG
的作用
NDEBUG
是一个 预处理宏变量,控制 assert
是否生效。
在 <assert.h>
中(标准库实现),大概长这样:
#ifdef NDEBUG
#define assert(ignore) ((void)0)
#else
#define assert(expr) ((expr) ? (void)0 : __assert_fail(...))
#endif
👉 意思是:
没有定义
NDEBUG
:assert
正常工作。定义了
NDEBUG
:assert
会被编译器替换成(void)0
,即什么都不做,彻底失效。
3. 如何启用/禁用 assert
默认情况
一般编译时不定义
NDEBUG
,所以assert
默认是启用的。
禁用 assert
(常在 release 模式)
手动在代码里加:
#define NDEBUG #include <assert.h>
或者在编译时定义:
g++ -DNDEBUG main.cpp -o main
这样 assert
宏在编译阶段就会被替换掉,不会有任何运行时开销。
4. 使用场景
调试阶段(Debug build):
用assert
来验证程序运行时的“假设”。比如:assert(ptr != NULL); // 这里假设指针不为空
发布阶段(Release build):
通常会加-DNDEBUG
禁用所有assert
,避免:运行时性能损耗。
在生产环境因为
assert
崩掉服务。
5. 注意点
assert
不适合替代正常的错误处理逻辑。Debug 模式下崩溃方便开发者发现问题。
Release 模式下它可能被编译掉,完全没效果。
👉 所以不要拿assert
来检查用户输入、网络异常等情况。
如果你想 即使在 Release 也强制检查,就写自己的检查逻辑:
if (!ptr) { fprintf(stderr, "fatal: null pointer\n"); exit(1); }
6. 比喻
assert
就像你写代码时的“安全带”,确保某个假设为真,否则立刻报警停车。NDEBUG
就像把安全带“剪掉”,让车可以随便跑,不会因为警报停下来。调试阶段:戴上安全带,保护自己。
发布阶段:去掉安全带,车能跑得更快,但要自己负责。
✅ 总结:
assert(expr)
:调试时验证假设,失败就中断。NDEBUG
:编译开关,定义后会让所有assert
失效。用法:调试阶段开着,发布阶段关掉。