SEH
可以让你程序在运行期发生错误时
,
捕捉到它
,
并且能按照你的意思做出处理
.
SEH
分为两个部分
:termination handling
和
exception handling
termination handling(
结束处理程序
)
visual c++
中是用这样的格式实现结束处理程序的
_try
{
//Guarded code
.......
}
_finally
{
//Termination handler
......
}
经过编译器和OS的合作.这个程序结构能使你在try块返回之前执行finally块中的处理程序,然后再跳出try块.也就是说在try块里面执行return/goto/continue/break等语句时,会在这些语句之前首先执行finally块中的代码,然后try块在返回.
用结束处理程序的好处呢就是可以使异常的处理代码集中放在一块.方便维护,也增加了程序的健壮性.但是在局部退出时,根据编译器和OS的不同,会产生不同大小的汇编代码(这些代码保证了在try提前推出之前先执行finally块).这样无形中增加了系统的负担.而如果把return/goto/continue/break等语句直接用_leave关键字替换,会使try块之间跳到结束的地方,即try块的右括号,try是正常流程退出,这样产生的汇编代码就很少.try是正常流程退出,减轻了系统的负担.
强制执行finally块有三种情况
-
从try块进入finally块的正常程序流程
-
局部展开:从try块中过早的退出(return/goto/continue/break),强制转移到finally块
-
全局展开(会在异常处理程序中说明)
在这一段最后再介绍一个API函数 Bool AbnormalTermination()..如果程序按正常流程退出try块返回FALSE.反之为TRUE
异常处理程序
代码结构:
_try
{
//Guarded code
.......
}
_exception(exception filter)
{
//exception handler
......
}
在异常处理程序的块中用return/goto/continue/break等语句不会造成速度和代码规模的影响,但是这个做法是不好的.强烈建议不要用.
上面代码中的filter只能是三个值
- EXCEPTION_EXECUTE_HANDLER :在对应的try块中,如果发生了异常,程序就会转到exception块的开头,开始执行.exception块中代码执行之后,程序转到exception块之后的第一条指令开始执行
- EXCEPTION_CONTINUE_EXECUTION:在对应的try块中产生了异常,程序转到exception块中执行.在执行完exception块中代码之后,重新执行try块
- EXCEPTION_CONTINUE_SEARCH:这个表示符号告诉系统,去查找前一个与exception块相匹配的try块,并调用这个try块的异常处理器