我们的程序为什么总是bug不断?
我们的程序通常会出现三个错误: 用户输入错误, 运行期错误以及异常。对于用户输入错误我们会进行很多的合法性检查,一般都是可以避免的,对于运行期错误就比较难办了,我们是最希望把bug在前期的过程的发现,如果需求期的一个bug流入到生产环境中的话那么损失就是无法估量的,客户可能会直接怀疑你家的设计能力。尽管我们都在层层的把关,还是有很多的bug会遗留到生产系统上去。
对运行期错误我们能做的是就是做尽量多的测试(UT/FT/ST 等等),尽可能的去测试各种user case。也做了很多的测试但是线上系统还是有很多处理不完的bug,agile是不是正的适合大型软件的开发,真的是不是每个人都能成为真正的全能手。这章主要是程序的异常处理和断言。怎样让系统检测到异常后进行合理的结束,并不是直接的crash,这里还是有很多的学问, 不同与erlang中的 let it crash, C里面提供了很多的异常处理机制,下面我们就来看看C中有那些合理的处理机制。
第一个就是longjmp和setjmp, 一个结构化的异常处理,setjmp设置一个异常处理点,然后发生异常的时候longjmp到之前set的地方,下面是一个简单的例子,我们检测除法异常如果除数为0我们则jmp到之前set的地方。
#include <setjmp.h>
#include <stdlib.h>
#include <stdio.h>
int div_by_zero_handled = 0;
jmp_buf Div_Failed;
int div(int n, int m) {
if (m == 0) {
if (div_by_zero_handled) {
longjmp(Div_Failed, 1);
}
}
return n / m;
}
int main() {
div_by_zero_handled = 1;
if (setjmp(Div_Failed)) {
printf("can't div by zero \n");
exit(EXIT_FAILURE);
}
int n = div(2, 0);
printf("----->%d\n", n);
return 0;
}
这里如果在div里面我们检测到除数是0, 那么longjump到之前set的地方, 程序的输出如下:
can't div by zero
下面就来看看在C语言里面这样通过longjmp和setjmp和宏实现一个类似C++ java中 try catch的功能。但这里需要强调一点的是异常处理要尽量的少用,正如书中所讲的一般只在大型应用程序中少量的使用,如果异常越来越多,这通常说明程序有更严重设计问题。
C++/java中的try catch 的语法是这样的:
try
S
catch (e1)
S1
catch (e2)
S2
catch (en)
Sn
Else
So
在e1, e2, en的地方我们通过setjmp创建了异常处理程序,如果S没有触发异常,将跳过程序程序,如果在S执行过程中产生了异常e,并且e是在e1...en之间的一个,那么S的执行被中断,控制立即转给相对应的Except从句总的语句。
最后还是要切记,在代码中异常处理要尽量少用。
-END-
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。