现在的位置: 首页 > 综合 > 正文

程序当中错误的产生、响应及处理

2014年03月19日 ⁄ 综合 ⁄ 共 1304字 ⁄ 字号 评论关闭
    在编写任何软件的时候都会遇到这样的问题:
    我调用了一个他人写的函数返回了错误标志,我是否应该打印一条错误信息呢?如果我选择了打印,假若被调用的函数也同样打印了错误信息,这样不就出现很多雷同的错误信息了吗?假若在函数调用栈上的所有函数都选择打印这样的错误信息,那么整个程序将出现无法控制的输出信息。
    在unix环境下,调用系统调用,调用C标准库都会产生错误,但是在这些函数当中都没有进行错误处理(打印),它们只是设置了全局变量errno,最后函数本身返回-1或NULL作为错误标志。在java和C++中的错误处理只是在出现错误的地方抛出异常。
    下面我们通过函数的层次来探索错误的最优处理方式。
函数的层次。
将所有函数按照层次划分:
0(产生)层:系统调用、语言提供的标准库、引用的其它库。
1(响应)层:调用0层的函数。
2层:调用1层的函数。
...
...
n(处理)层:调用n - 1层的函数
上面的函数层次即我们的调用堆栈,0(产生)层只是设置错误信息,可以是errno,可以是某个字符串,可以是某个异常,可以是某个具体的对象。1(响应)层将这些信息包装一次设置成自己的错误信息,n(处理)层对错误信息做最终处理。
0(产生)层为系统层,该层函数的内部运行逻辑我们不会关心,只关心它的错误标志。1 到 n为应用层,应用层当中出现错误的场景有3中,如下:
场景1: 这一种情况下,假若function为0层函数则设置错误标志及错误信息,否则只是返回。
if(flag == function()){
              set error flag and message
    return err;
}
场景2:这一种情况下,一定会设置错误标志及错误信息。
if(flag1 == flag2){
    set error flag and message
    return err;
}
场景3:这一种情况下,先进行分解,分解后为两个场景1和一个场景2,并且两个场景1势必会在场景2之前运行,其本质为场景1和场景2的组合,所以分别按照场景1和场景2处理即可。
if(function1() == function2()){
    set error flag and message
    return err;
}
解决方案。
在1层进行错误响应,在n层做错误处理。通俗点讲即只要调用系统调用、库函数或外部库的函数,如果产生了错误那么在调用的地方便设置错误信息,将处理部分的所有一切留给开发者认为要处理错误的地方。其模型如下:
const char* err_msg = NULL;
int fun2(){
    /*error occur,for example call read system call*/
    err_msg = "in function fun error occur";
    return -1;
}

int fun1(){
    int ret = 0;
    ret = fun2();
    if(-1 == ret){
        return -1;
    }
    return 0;
}

int main(){
    int ret = 0;
    ret = fun1();
    /*we found the n level function fun1 return error value*/
    if(-1 == ret){
        printf("Error:%s\n",err_msg);
    }
}

抱歉!评论已关闭.