Structed Exception Handler 学习总结(四)

1.  try-finally 语句的基本形式

__try



{



    //guarded code



}



__finally



{



    //termination handler



}

termination handler无论在guarded code以何种方式退出都会被调用。guarded code的退出方式有如下三种:

a. 正常退出该代码块

b. 在执行guarded code时发生异常

c. 在执行guarded code时遇到return语句或者goto语句(无条件跳转)

在这三种情况下termination handler都会被执行。其中第一种方式,常常用来对guarded code中申请的资源进行释放和清理,这也是try-finally语句最为常见的一种用法。

 

2.  多个finally块的执行流程

For example, suppose a series of function calls links function A to function D, as shown in the following figure. Each function has one termination handler. If an exception is raised in function D and handled in A, the termination handlers are called in this order as the system unwinds the stack: D, C, B.

Order of Termination-Handler Execution

Structed Exception Handler 学习总结(四)

实例代码如下:

void FA()



{



     __try



     {



         _tprintf_s(TEXT("FA: __try\n"));



     }



     __finally



     {



         _tprintf_s(TEXT("FA: __finally\n"));



     }



     _tprintf_s(TEXT("FA: FA\n"));



}



void FB()



{



     __try



     {



         FA();



         _tprintf_s(TEXT("FB: __try\n"));



     }



     __finally



     {



         _tprintf_s(TEXT("FB: __finally\n"));



     }



     _tprintf_s(TEXT("FB: FB\n"));



}



void FC()



{



     __try



     {



         FB();



         _tprintf_s(TEXT("FC: __try\n"));



     }



     __finally



     {



         _tprintf_s(TEXT("FC: __finally\n"));



     }



     _tprintf_s(TEXT("FC: FC\n"));



}



int _tmain()



{



     __try



     {



         FC();



         _tprintf_s(TEXT("main: __try\n"));



     }



     __finally



     {



         _tprintf_s(TEXT("main: __finally\n"));



     }



        _tprintf_s(TEXT("main: main\n"));



     return 0;



}

 

其执行结果如下:

Structed Exception Handler 学习总结(四)

可见所以的finally块都被执行了。

 

3.  编写try-finally语句的最佳实践

Structed Exception Handler 学习总结(四)

在编写try-finally块时,要注意尽量不要使用return,continue, break,goto语句,因为SEH机制为了保证__finally块中语句被执行,会生成额外的代码来实现,这对程序的性能是有害的(当然,如果我们使用了这些语句,程序也是可以编译通过的,也没有错误),有可能大量使用栈,从而导致栈异常。

 

4.  try-finally语句的使用示例

//没有使用SEH的代码

Structed Exception Handler 学习总结(四)

在编写上述函数时未使用SEH机制(try-finally),其中为了完成对错误的处理,在该函数的实现中出现了大量的用于流程控制(函数返回)的return语句,同时还大量重复使用了CloseHandler和VirtualFree函数来对该函数申请的资源进行处理,这些错误检查代码使得整个函数难以阅读,进而造成该函数难以理解,修改和维护

 

//使用SEH来编写该函数

Structed Exception Handler 学习总结(四)

如上图所示,整个函数的资源清理全部放到__finally块中,使得整个函数的代码简洁,干净了许多,代码也更容易阅读和维护。

使用try-finally块的理由:

你可能感兴趣的:(exception)