我们在撸代码的时候,经常需要对代码的安全性进行检查,例如:
1. 指针是否为空?
2. 被除数是否为 0?
3. 函数调用的返回结果是否有效?
4. 打开一个文件是否成功?
对这一类的边界条件进行检查的手段,一般都是使用 if 或者 assert 断言,无论使用哪一个,都可以达到检查的目的。那么是否就意味着:这两者可以随便使用,想起来哪个就用哪个?
这篇小短文我们就来掰扯掰扯:在不同的场景下,到底是应该用 if,还是应该使用 assert 断言?
写这篇文章的时候,我想起了孔乙己老先生的那个问题:茴香豆的“茴”字有几种写法?
似乎我们没有必要来纠结应该怎么选择,因为都能够实现想要的功能。以前我也是这么想的,但是,现在我不这么认为。
成为技术大牛、拿到更好的offer,也许就在这些细微之间就分出了胜负。
二、assert 断言
刚才,我问了下旁边的一位工作 5 年多的嵌入式开发者:if 和 assert 如何选择?他说:assert 是干什么的?!
看来,有必要先简单说一下 assert 断言。
assert() 的原型是:
void assert(int expression);
1. 如果宏的参数求值结果为非零值,则不做任何操作(no action);
2. 如果宏的参数是零值,就打印诊断消息,然后调用abort()。
例如下面的代码:
#include <assert.h>
int my_div(int a, int b)
{
assert(0 != b);
return a / b;
}
1. 当 b 不为 0 时,assert 断言什么都不做,程序往下执行;
2. 当 b 为 0 时,assert 断言就打印错误信息,然后终止程序;
从功能上来说,assert(0 != b); 与下面的代码等价:
if (0 == b)
{
fprintf(stderr, "b is zero...");
abort();
}
assert 是一个宏,不是一个函数
在 assert.h 头文件中,有如下定义:
#ifdef NDEBUG
#define assert(condition) ((void)0)
#else
#define assert(condition) /*implementation defined*/
#endif
既然是宏定义,说明是在预处理的时候进行宏替换。