代码安全性和健壮性:如何在if和assert中做决定?
我们在撸代码的时候,经常需要对代码的安全性进行检查,例如: 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 既然是宏定义,说明是在预处理的时候进行宏替换。 (编辑:ASP站长网) |