设为首页 加入收藏

TOP

C语言异常与断言接口与实现(三)
2015-01-22 20:49:51 来源: 作者: 【 】 浏览:37
Tags:语言 异常 断言 接口 实现
uf env;
? ? const char *file;
? ? int line;
? ? const T *exception;
};
extern Except_Frame *Except_stack;
Except_stack指向异常栈顶的异常帧,每个帧的prev字段指向它的前一帧,产生一个异常就是将异常的地址存在exception字段中,并分别在file和line字段中保存异常的附属信息--异常产生的文件以及行号
?
TRY从句将一个新的Except_Frame压入异常栈,并调用setjmp,由RAISE和RERAISE调用Except_raise填充栈顶帧的字段exception、file和line,从异常栈中弹出栈顶Exception_Frame,然后调用longjmp,EXCEPT从句检查该帧中的exception字段,决定应该用哪个处理程序。FINALLY从句执行清除代码,并重新产生已弹出的异常帧中存储的异常。
?
宏指令TRY、EXCEPT、ELSE、FINALLY_TRY一起将TRY-EXCEPT语句转化成如下形式的语句:
?
do {
?
  creat and push an Except_Frame
?
  if(first return from setjmp) {
?
    S
?
  } else if (exception is e1) {
?
    S1
?
  ……
?
  } else if (exception is en) {
?
    Sn
?
  } else {
?
    S0
?
  }
?
  if(an exception occurrend and wasn't handled)
?
    RERAISE;
?
} while(0)
?
Exception_Frame的空间分配很简单,在由TRY开始的do-while主体中的复合语句内部声明一个该类型的局部变量即可:
?
#define TRY do { \
? ? volatile int Except_flag; \
? ? Except_Frame Except_frame; \
? ? Except_frame.prev = Except_stack; \
? ? Except_stack = &Except_frame; ?\
? ? Except_flag = setjmp(Except_frame.env); \
? ? if (Except_flag == Except_entered) {
在TRY语句内有四种状态,由下面的枚举标识符给出
?
enum { Except_entered=0, Except_raised,
? ? ? ?Except_handled, ? Except_finalized };
setjmp的第一个返回值将Except_flag设置为Except_entered,表示进入TRY语句,并且将某个异常帧压入异常栈,Except_entered必须为0,因为setjmp首次调用的返回值为0,随后,setjmp的返回值将被设为Except_raised,表示发生了异常,处理程序将Except_flag的值设成Except_handled,表示处理程序已经对异常进行了处理。
?
#define TRY do { \
? ? volatile int Except_flag; \
? ? Except_Frame Except_frame; \
? ? Except_frame.prev = Except_stack; \
? ? Except_stack = &Except_frame; ?\
? ? Except_flag = setjmp(Except_frame.env); \
? ? if (Except_flag == Except_entered) {
#define EXCEPT(e) \
? ? ? ? if (Except_flag == Except_entered) Except_stack = Except_stack->prev; \
? ? } else if (Except_frame.exception == &(e)) { \
? ? ? ? Except_flag = Except_handled;
#define ELSE \
? ? ? ? if (Except_flag == Except_entered) Except_stack = Except_stack->prev; \
? ? } else { \
? ? ? ? Except_flag = Except_handled;
#define FINALLY \
? ? ? ? if (Except_flag == Except_entered) Except_stack = Except_stack->prev; \
? ? } { \
? ? ? ? if (Except_flag == Except_entered) \
? ? ? ? ? ? Except_flag = Except_finalized;
#define END_TRY \
? ? ? ? if (Except_flag == Except_entered) Except_stack = Except_stack->prev; \
? ? ? ? } if (Except_flag == Except_raised) RERAISE; \
} while (0)
最后实现代码如下:
?
#include
#include
#include "assert.h"
#include "except.h"
#define T Except_T
#ifdef WIN32
__declspec(thread)
#endif
Except_Frame *Except_stack = NULL;
void Except_raise(const T *e, const char *file,
? ? int line) {
? ? Except_Frame *p = Except_stack;
? ? assert(e);
? ? if (p == NULL) {
? ? ? ? fprintf(stderr, "Uncaught exception");
? ? ? ? if (e->reason)
? ? ? ? ? ? fprintf(stderr, " %s", e->reason);
? ? ? ? else
? ? ? ? ? ? fprintf(stderr, " at 0x%p", e);
? ? ? ? if (file && line > 0)
? ? ? ? ? ? fprintf(stderr, " raised at %s:%d\n", file, line);
? ? ? ? fprintf(stderr, "aborting...\n");
? ? ? ? fflush(stderr);
? ? ? ? abort();
? ? }
? ? p->exception = e;
? ? p->file = file;
? ? p->line = line;
? ? Except_stack = Except_stack->prev;
? ? longjmp(p->env, Except_raised);
}
首页 上一页 1 2 3 下一页 尾页 3/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇数据结构(C实现)------- 遍历二.. 下一篇C语言指针――指针的运算

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: