Funcenstein4
Let's take a look at one more termination-handling scenario:
In Funcenstein4, the try block will execute and try to return the value of dwTemp (5) back to Funcenstein4's caller. As noted in the discussion of Funcenstein2, trying to return prematurely from a try block causes the generation of code that puts the return value into a temporary variable created by the compiler. Then the code inside the finally block is executed. Notice that in this variation on Funcenstein2 I have added a return statement to the finally block. Will Funcenstein4 return 5 or 103 to the caller? The answer is 103 because the return statement in the finally block causes the value 103 to be stored in the same temporary variable in which the value 5 has been stored, overwriting the5. When the finally block completes execution, the value now in the temporary variable (103) is returned from Funcenstein4 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 the try block, and we've also seen termination handlers produce an unwanted result because they prevented a premature exit of the try block. A good rule of thumb is to avoid any statements that would cause a premature exit of the try block part of a termination handler. In fact, it is always best to remove all returns, continues, breaks, gotos, and so on from inside both the try and finally 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 the try 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,代码执行速度也会快得多。而且,代码也会更易读、维护。