异常处理 - 断言

断言

简介

  • 断言(assertion)是编程语言中用来检查表达式是否为true的机制。

接口和使用

  1. 接口描述
  • 在C/C++语言中,断言是定义于assert.h的一些宏,如下:
头文件:  #include "assert.h" 
接口定义:void assert(int expression);
  1. 工作流程
  • 断言语句运行时先计算表达式expression,如果其值为假(即为0),那么它先向stderr打印一条出错信息,然后再调用abort来终止程序运行。
  1. 使用
  • 断言的使用较为简单,如下:
void test(void *a, int b){
    assert(a != NULL); //判断指针a不为NULL
    assert(b > 0); //判断整数b大于0
    ...
}
  • 断言启用/关闭:默认情况下断言是启用的,对应Debug版本;编译时加上宏定义"#define NDEBUG",断言就会被替换为空,对应Release版本。
  1. 运行
  • 断言语句的表达式为真时:不会有任何动作
  • 断言语句的表达式为假时:会打印些错误信息,错误信息比较详细,可以很方便的定位代码,如下:
Launcher: Phone_PopupWidget.cpp:119: void Phone_PopupWidget::hidePopup(): Assertion `m_Loading' failed.

断言使用经验

  • 断言是编程语言中比较基础的功能,但是对于大部分初学者不清楚为什么要用断言,即使是实际工作中我也发现很多程序员几乎不使用断言。
  • 断言和if的功能很类似,但是if语句更为简单,明了,因此很多程序员会使用if语句来做检查函数参数等异常情况判断处理,如下:
void test(void *a){
    if (NULL == a){
        ...
        return;
    }
}
  • 断言和if判断的使用并不是可以随意替换,应该互为补充来充分利用到它们的优点。

if 判断的问题

  1. if判断使用比较繁杂:如果对每个参数进行判断以及异常处理,if语句的使用量会比较大,并且会导致代码比较长,很多代码都做不到这点,往往只会判断一些关键条件。
  2. 使用if判断可能会导致问题的掩盖:由于if判断使用繁杂,很多时候的异常处理会比较敷衍,可能只是加些打印来提示程序员,或者从别的地方拷贝过来,改下条件判断,打印语句可能都忘了改,因此如果程序没出现异常现象,一些小问题往往会被忽略。
  3. 性能问题:if判断一直存在,即使是在release版本中,程序稳定后,大部分情况下一些基础的判断已经没必要存在,不断的校验只会浪费一定的性能。

if和断言的使用场景

  • 为了避免以上if判断的问题,就需要使用断言,一些情况下需要使用断言而不是if判断,什么时候应该使用if什么时候应该使用断言?这需要理解它们的区别。
  1. 断言和if判断的区别:断言的作用是明确区分程序运行时可能出现的预期和非预期的情况,而if判断是处理程序运行时可能出现的预期情况中的异常情况,if判断不支持更改预期情况的范围,所以其预期情况的范围是所有的可能情况,而断言条件更改的是预期情况的范围,DEBUG版本时定义一些预期条件,出现预料之外的情况,那就是bug,解决和测试确认后,预料之外的情况不会出现后,就可以关闭断言校验,即为RELEASE版本。
  2. RELEASE版本关闭了断言,即解决了if判断的性能问题。
  3. 断言的异常处理是结束程序运行,这样程序员能够明确出现了意料之外的情况,不会被忽视。
  4. 使用断言还是if判断,需要明确预期,哪些条件是预期的,哪些是预期之外的,断言来标记预期情况范围,预期之内的异常情况需要使用if判断来做异常处理。
  • 打个形象点的比方,断言和if像是两个安检,断言的行为像是每次抓到破坏者(不符合预期结果)就交给警察(程序员),要求警察彻底解决掉,长时间没破坏者了,断言就圆满收工(生成Release版本,关闭断言),而if的行为像是每次抓到破坏者,后续行为由程序员决定,可能仅仅是让破坏者原路返回(直接return),也不管不顾,或者做些警告(加些错误提示),但是后续,破坏者可能又出现,甚至可能出现在没有安检的地方,因此使用if必须处处设置安检并且时刻坚守岗位,一疏忽可能导致破坏者溜进去了(Debug版本和Release版本都必须存在)。

使用注意

  1. 由于断言生效会终止程序运行,因此只能在Debug阶段使用断言,Release版本编译时需要带NDEBUG宏。
  2. 断言的目的是在不符合预期的情况时结束程序,有些函数返回NULL,以及函数参数为NULL,可能是符合预期的行为,不能直接断言,需要明确预期结果。
  3. 如果变量参数来自于系统内部,变量值可预料,则可使用断言;如果来源于外部,例如:用户输入,是不可预期的,用户传任何值都可能,则应该使用if判断来检查和处理非法的数据。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值