`
sony-soft
  • 浏览: 1021746 次
文章分类
社区版块
存档分类
最新评论

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

 
阅读更多

Funcenstein4

Let's take a look at one more termination-handling scenario:

DWORD Funcenstein4() {
   DWORD dwTemp;
   // 1. Do any processing here.
   ...
   __try {
      // 2. Request permission to access
      //    protected data, and then use it.
      WaitForSingleObject(g_hSem, INFINITE);

      g_dwProtectedData = 5;
      dwTemp = g_dwProtectedData;

      // Return the new value.
      return(dwTemp);
   }
   __finally {
      // 3. Allow others to use protected data.
      ReleaseSemaphore(g_hSem, 1, NULL);
      return(103);
   }

   // Continue processing--this code will never execute.
   dwTemp = 9;
   return(dwTemp);
}

In Funcenstein4, thetry block will execute and try to return the value ofdwTemp (5) back toFuncenstein4's caller. As noted in the discussion ofFuncenstein2, trying to return prematurely from atry block causes the generation of code that puts the return value into a temporary variable created by the compiler. Then the code inside thefinally block is executed. Notice that in this variation onFuncenstein2 I have added areturn statement to thefinally block. WillFuncenstein4 return5 or103 to the caller? The answer is103 because thereturn statement in thefinally block causes the value103 to be stored in the same temporary variable in which the value5 has been stored, overwriting the5. When thefinally block completes execution, the value now in the temporary variable (103) is returned fromFuncenstein4 to its caller.

本例中,try部分将返回dwTemp(值为5)。如前所述,在try中的return会导致编译器产生额外的代码用来把返回值放到一个临时变量里,然后去执行finally中的内容。与前面的例子不同的是,本例在finally里增加了一个return,这次会返回5还是103呢?答案是103,因为finally中dereturn导致103保存到了刚才保存5的临时变量。

We've seen termination handlers do an effective job of rescuing execution from a premature exit of thetry block, and we've also seen termination handlers produce an unwanted result because they prevented a premature exit of thetry block. A good rule of thumb is to avoid any statements thatwould cause a premature exit of thetry block part of a termination handler. In fact, it is always best to remove allreturns,continues,breaks,gotos, and so on from inside both thetry andfinally blocks of a termination handler and to put these statements outside the handler. Such a practice will cause the compiler to generate both a smaller amount of code—because it won't have to catch premature exits from thetry block—and faster code, because it will have fewer instructions to execute in order to perform the local unwind. In addition, your code will be much easier to read and maintain.

本我们看到了termination hander在try中出现提前退出时产生的后果。一条很好的原则就是,不要在try中制造提前退出。具体地讲,就是在try、finally里不要出现return、continue、break、goto。这样编译器产生的代码会少很多,而且由于不需要执行local unwind,代码执行速度也会快得多。而且,代码也会更易读、维护。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics