1. try-except语句的执行流程
try-except语句的一般形式:
__try { //guarded section } __except(filter expression) { //exception handler }
首先,明确几个术语,__try子句后面的复合语句被称作guarded section,__except子句括号中的表达式称为filter expression,__except子句后面的复合语句称为exception handler
执行流程如下:
(1)guarded section被执行
(2)如果执行(1)时未发生异常,则直接执行exception handler复合语句后面的语句
(3)如果执行(1)时发生了异常(注意:发生的这个异常可以是guarded section中的代码引发的,也可以是guarded section中调用其他函数,从而由该函数引发的),此时filter expression就会被计算(evaluated),filter expression的计算结果有三个值,这三个值决定了该异常应该被如何处理:
a. EXCEPTION_CONTINUE_EXECUTION (–1) 这个值表示该异常被忽略,不调用exception handler,同时将程序的执行控制流程转到异常发生的指令处继续执行,实际上这时“死循环”就出现了。执行控制流程转到异常发生的指令处继续执行,又引发异常,filter expression被求值,得到EXCEPTION_CONTINUE_EXECUTION,程序又被转到异常发生的指令处继续执行,如此循环往复,从而出现了“死循环”。所以这个值在使用的时候要特别的小心。
b. EXCEPTION_CONTINUE_SEARCH (0) 这个值表示在调用堆栈中继续搜索合适的exception handler,当前的exception handler不会被调用。如果,filter expression的计算结果是这个值,实际上表明这个exception并不是当前exception handler所要处理的exception,所以,当前的exception handler 不能也不应该被调用。
c. EXCEPTION_EXECUTE_HANDLER (1) 这个值表示此时应该调用当前的exception handler来处理guarded section中发生的exception,并且当调用完exception handler之后,程序如果没有被返回(return),则程序继续执行exception handler复合语句后面的语句。这个值说明当前的exception handler就是为处理guarded section中发生的exception所准备的,自然exception handler就被调用了。
所以,综上所述只有当filter expression被计算为EXCEPTION_EXECUTE_HANDLER时,当前的exception handler才会被调用,否则exception handler是不会被调用的。
注意:a. Because the __ except expression is evaluated as a C expression, it is limited to a single value, the conditional-expression operator, or the comma operator. If more extensive processing is required, the expression can call a routine that returns one of the three values listed above.
b. The filter expression of a frame-based exception handler is an expression that is evaluated by the system when an exception occurs within the guarded body. This evaluation results in one of the following actions by the system.
(1) The system stops its search for an exception handler, restores the machine state, and continues thread execution at the point at which the exception occurred.
(2) The system continues its search for an exception handler.
(3) The system transfers control to the exception handler, and thread execution continues sequentially in the stack frame in which the exception handler is found.If the handler is not in the stack frame in which the exception occurred, the system unwinds the stack, leaving the current stack frame and any other stack frames until it is back to the exception handler's stack frame. Before an exception handler is executed, termination handlers are executed for any guarded bodies of code that terminated as a result of the transfer of control to the exception handler.
2. 当一个异常被try-excpt语句捕获并处理了之后,这个try-ecept语句块中就没那种被捕获的异常了。也就是说如下代码中最外层的__excep块永远不会被执行
__try { __try { Div(1, 0, &r);//抛出一个除0异常 } __except(EXCEPTION_EXECUTE_HANDLER) { _tprintf_s(TEXT("main: __except.\n")); return -1; } } __except(EXCEPTION_EXECUTE_HANDLER) { _tprintf_s(TEXT("maimn out: __except.\n")); return FALSE; }
3. 编写exception handler代码时的一些限制:
The principal limitation to using exception handlers in code is that you cannot use a goto statement to jump into a __try statement block. Instead, you must enter the statement block through normal flow of control. You can jump out of a __try statement block and nest exception handlers as you choose.