zoukankan      html  css  js  c++  java
  • C 工具库2:异常处理

    使用setjmp,longjmp实现的C与言异常处理框架。

    提供 抛出异常,捕获异常等功能。

    exception.h

    #ifndef _EXCEPTION_H
    #define _EXCEPTION_H

    #define except_alloc_failed 1 //内存分配失败
    #define except_list_empty 2 //list_pop操作,当list为空触发
    //............

    #endif

    except.h

    #ifndef _EXCEPT_H
    #define _EXCEPT_H
    #include <setjmp.h>
    #include <stdio.h>
    #include <assert.h>

    struct exception_frame
    {
    struct exception_frame *pre;
    jmp_buf jumpbuffer;
    int exception;
    int line;
    const char *file;
    };

    extern struct exception_frame *exception_stack;

    extern void exception_throw(int code,const char *file,int line);

    /*一个函数第一次使用TRY前必须定义,如果重复定义会出现不确定的行为
    * 主要是为了正确处理在TRY代码内的RETURN
    */
    #define FUNCTION_TRY int function_except_stack_count = 0;
    #define TRY do{\
    ++function_except_stack_count;\
    struct exception_frame frame;\
    frame.pre = exception_stack;\
    exception_stack = &frame;\
    if((frame.exception = setjmp(frame.jumpbuffer)) == 0)

    #define THROW(EXP) exception_throw(EXP,__FILE__,__LINE__)

    #define RETHROW exception_throw(frame.exception,frame.file,frame.line)

    #define CATCH(EXP) else if(EXP == frame.exception ? frame.exception = 0,1:0)

    #define CATCH_ALL else if(frame.exception ? frame.exception = 0,1:0)

    #define ENDTRY --function_except_stack_count;\
    if(frame.exception){\
    exception_throw(frame.exception,frame.file,frame.line);}\
    else if(exception_stack){\
    exception_stack = exception_stack->pre;\
    }\
    }while(0);

    #define FINALLY
    /*根据当前函数中try的处理情况丢弃数量正确的异常栈,再返回*/
    #define RETURN(R) do{if(exception_stack){\
    while(exception_stack && function_except_stack_count>0){\
    function_except_stack_count--;\
    exception_stack = exception_stack->pre;\
    }\
    }\
    return R;\
    }while(0)

    #endif

    except.c

    #include "except.h"
    #include <stdlib.h>

    struct exception_frame *exception_stack = 0;

    void exception_throw(int code,const char *file,int line)
    {
    if(exception_stack)
    {

    exception_stack->exception = code;
    exception_stack->file = file;
    exception_stack->line = line;
    struct exception_frame *frame = exception_stack;
    exception_stack = frame->pre;
    longjmp(frame->jumpbuffer,code);
    }
    else
    {
    printf("unsolved exception %d,file:%s line:%d\n",code,file,line);
    }
    }

    test.c

    #include "except.h"

    int func1()
    {
    FUNCTION_TRY
    TRY{
    TRY{
    RETURN(0);
    func2();
    }
    printf("func1 %d\n",function_except_stack_count);
    ENDTRY
    }
    CATCH(1)
    {
    printf("catch a exception\n");
    }
    FINALLY
    {
    printf("func1 %d\n",function_except_stack_count);
    RETURN(0);
    printf("func1 finally\n");
    }
    ENDTRY
    }

    int func2()
    {
    printf("beginjump\n");
    THROW(2);
    printf("end of func2\n");
    }

    int main()
    {

    FUNCTION_TRY
    TRY{
    func1();
    printf("return\n");
    TRY{
    func1();
    }
    CATCH(2)
    {
    printf("catch a exception 2\n");
    TRY{
    THROW(2);
    }
    ENDTRY

    }
    FINALLY
    {
    printf("finally\n");
    }
    ENDTRY
    }
    CATCH_ALL
    {
    printf("catch all\n");
    }
    ENDTRY
    return 0;
    }






  • 相关阅读:
    《数据库原理》课程笔记 (Ch04-数据库管理系统)
    《数据库原理》课程笔记 (Ch03-数据库语言)
    《操作系统》课程笔记(Ch07-死锁)
    《数据库原理》课程笔记 (Ch02-数据模型)
    《数据库原理》课程笔记 (Ch01-引论)
    《计算机网络》课程笔记 (Ch02-应用层)
    《ES6标准入门》读书笔记 第5章
    《ES6标准入门》读书笔记 第4章
    《ES6标准入门》读书笔记 第3章
    《计算机网络》课程笔记 (Ch01-计算机网络和因特网)
  • 原文地址:https://www.cnblogs.com/sniperHW/p/2429611.html
Copyright © 2011-2022 走看看