Chapter 23: Termination Handlers(2)Understanding Termination Handlers by Example(5)

Notes About the finally Block

So far we have explicitly identified two scenarios that force the finally block to be executed:

到目前为止,我们确定的两种导致finally执行的情形:

  • Normal flow of control from the try block into the finally block 

    正常情况,从try中进入

  • Local unwind: premature exit from the try block (goto,longjump,continue,break, return, and so on) forcing control to the finally block

    Local unwind,使用goto等导致提前退出try

A third scenario—a global unwind—occurred without explicit identification as such in the Funcfurter1 function we saw on page 663. Inside the try block of this function was a call to the Funcinator function. Before Windows Vista, if the Funcinator function caused a memory access violation, a global unwind caused Funcfurter1's finally block to execute. As of Windows Vista, a global unwind is not triggered by default, so the finally block is not executed. "The SEH Termination Sample Application" on page 673 gives you a first glance at what triggers a global unwind, and we'll look at global unwinding in greater detail in the next two chapters.

第三种情形----global unwind----?

Code in a finally block always starts executing as a result of one of these three situations. To determine which of the three possibilities caused the finally block to execute, you can call the intrinsic function AbnormalTermination:

可以通过函数判断是因为什么导致finally被执行

BOOL AbnormalTermination();

 Note 

An intrinsic function is a special function recognized by the compiler. The compiler generates the code for the function inline rather than generating code to call the function. For example, memcpy is an intrinsic function (if the/Oi compiler switch is specified). When the compiler sees a call tomemcpy, it puts thememcpy code directly into the function that calledmemcpy instead of generating a call to thememcpy function. This usually has the effect of making your code run faster at the expense of code size.

The intrinsic AbnormalTermination function is different from the intrinsicmemcpy function in that it exists only in an intrinsic form. No C/C++ run-time library contains theAbnormalTermination function.

This intrinsic function can be called only from inside a finally block, and it returns a Boolean value indicating whether the try block associated with the finally block was exited prematurely. In other words, if the flow of control leaves the try block and naturally enters the finally block, AbnormalTermination will return FALSE. If the flow of control exits the try block abnormally— usually because a local unwind has been caused by a goto,return,break, or continue statement or because a global unwind has been caused by a memory access violation or another exception— a call to AbnormalTermination will return TRUE. It is impossible to determine whether a finally block is executing because of a global unwind or because of a local unwind. This is usually not a problem because you have, of course, avoided writing code that performs local unwinds.

这个函数只能在finally中被调用,它的返回值表明try中的代码是否提前退出了。换句话说,如果流程是自然进入finally,这个函数返回FALSE。如果是提前退出try或者是由其他异常产生的global unwind,这个函数返回TRUE。目前没办法区别local unwind和global unwind。通常这不是问题,因为你可以在写代码的时候避免local unwind。

Funcfurter2

Here is Funcfurter2, which demonstrates use of the AbnormalTermination intrinsic function:

DWORD Funcfurter2() { DWORD dwTemp; // 1. Do any processing here. ... __try { // 2. Request permission to access // protected data, and then use it. WaitForSingleObject(g_hSem, INFINITE); dwTemp = Funcinator(g_dwProtectedData); } __finally { // 3. Allow others to use protected data. ReleaseSemaphore(g_hSem, 1, NULL); if (!AbnormalTermination()) { // No errors occurred in the try block, and // control flowed naturally from try into finally. ... } else { // Something caused an exception, and // because there is no code in the try block // that would cause a premature exit, we must // be executing in the finally block // because of a global unwind. // If there were a goto in the try block, // we wouldn't know how we got here. ... } } // 4. Continue processing. return(dwTemp); }

Now that you know how to write termination handlers, you'll see that they can be even more useful and important when we look at exception filters and exception handlers in the next chapter. Before we move on, let's review the reasons for using termination handlers:

  • They simplify error processing because all cleanup is in one location and is guaranteed to execute.

  • They improve program readability.

  • They make code easier to maintain.

  • They have minimal speed and size overhead if used correctly.


转载于:https://www.cnblogs.com/zz962/archive/2011/10/11/2209698.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值