浅析assert宏
文章目录
前言
首先声明一点,断言(assert)是宏,而非函数。
assert 宏的原型定义在 <assert.h>(C)、(C++)中。其作用是如果它的条件返回错误,则终止程序执行。
1. 简单的断言案例
cpp
#include <cassert> // cpp包含的头文件
void test1()
{
int x = 10;
assert(x == 20);
}
运行结果:
可以看到输出会把源码文件,行号错误位置,提示出来!
2. 断言与正常错误处理
- 断言主要用于检查逻辑上不可能的情况。
例如,它们可用于检查代码在开始运行之前所期望的状态,或者在运行完成后检查状态。与正常的错误处理不同,断言通常在运行时被禁用。
- 忽略断言,在代码开头加上:
c++
#define NDEBUG // 加上这行,则 assert 不可用
示例代码:
为什么加了 #define NDEBUG
语句assert宏仍然在发挥作用?特别注意,用于禁用 assert 宏的该语句应该 置于 #include<assert.h>(或)之前!
3. 断言的应用场景
一般来说,assert 和异常都是用来检测程序中的错误和异常情况的,但它们的使用场景和目的有所不同。
- assert 适合用于验证程序内部的逻辑和不变量,即那些在正常情况下不应该发生的错误 ,比如参数的类型和范围,函数的返回值,循环的终止条件等。如果 assert 失败,说明程序中存在严重的缺陷或者假设不成立,需要立即终止程序并进行调试异常适合用于处理程序外部的错误和异常情况,即那些由用户输入,网络通信,文件操作,数据库访问等引起的错误,比如输入不合法,网络断开,文件不存在,数据库连接失败等。
- 如果发生异常,程序可以捕获并处理异常,或者向上层抛出异常,以便恢复程序的正常运行或者给出友好的提示。
因此,assert 和异常的区别可以归纳为以下几点:
- assert 是一种调试工具,用于开发和测试阶段,可以在编译或运行时关闭 ,而异常是一种错误处理机制,用于生产环境,不能被关闭。
- assert 用于检查程序内部的错误,如果失败,程序会终止,而异常用于处理程序外部的错误,如果发生,程序可以继续执行。
- assert 不检查错误类型,只有一个 AssertionError,而异常有多种类型,可以根据不同的类型进行不同的处理。
- assert 的参数是一个布尔表达式,而异常的参数是一个异常对象,可以携带更多的信息。
总结
assert 宏的优点是可以在开发和调试阶段快速发现和定位程序中的错误,提高代码的可测试性和可靠性。assert 宏的缺点是可能会影响程序的性能,暴露敏感信息,或者在生产环境中导致令用户困惑的行为。
因此,通常在发布程序时会禁用 assert 宏,只在内部调试版本中启用。禁用 assert 宏的方法是在包含 <assert.h> 头文件之前定义 NDEBUG 宏,或者在编译命令行中定义 NDEBUG 宏。