assert宏 Release版本
2026/7/8大约 2 分钟
assert宏 Release版本
assert是调试用的断言宏:
#include <assert.h>
assert(ptr != NULL); // 条件为假时终止程序并打印信息- 条件为假时调用
abort()终止程序 - 定义
NDEBUG宏后assert被完全移除(零开销)
例子
#include <assert.h>
#include <stdio.h>
void set_speed(int *ptr, int speed) {
assert(ptr != NULL); // 断言
*ptr = speed;
}
int main() {
int speed = 100;
set_speed(&speed, 50); // 正常,ptr非空
printf("speed = %d\n", speed);
set_speed(NULL, 50); // 触发断言!
return 0;
}运行到set_speed(NULL, 50)时,程序会打印类似:
speed = 50
test.c:6: set_speed: Assertion `ptr != NULL' failed.
Aborted (core dumped)注意信息很详细:文件名、行号、函数名、断言表达式的原始文本全都打印出来了——这就是为什么assert比if (ptr == NULL) return;更适合快速调试定位问题,一眼就知道哪个文件哪一行出的问题,不用自己写打印语句。
底层
if (!(ptr != NULL)) {
fprintf(stderr, "%s:%d: %s: Assertion `%s' failed.\n", __FILE__, __LINE__, __func__, "ptr != NULL");
abort();
}在release版本下,在编译的时候会把断言优化掉,不会直接终止程序。
思路:记录错误日志(方便事后分析),然后走一条尽量安全的兜底逻辑(比如返回错误码、进入安全模式),而不是直接终止整个程序。
为什么这样设计:嵌入式设备(比如工业控制器、汽车ECU)Release版本直接abort()是很危险的——如果设备正在控制电机、刹车、阀门,程序突然abort死机,可能比"带着小bug继续跑"更糟糕。
Release版本处理:
- 编译时加
-DNDEBUG,所有assert变成空操作 - 或者自定义assert宏,Release版记录日志而非终止
嵌入式中的实践:Debug版用assert快速定位bug,Release版用错误码+日志替代。

