在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
本文转自 vipxiaotian(CSDN) 请参考下面一段简单的语句块: 1: try 大家有没有想过执行到第七步之后会出现什么结果?line7是一条return语句,按道理来说return语句的作用就是跳出当前函数并继续调用地址的下一条语句,那么说就不执行finally,但是我想大家应该都记得finally的作用:确保有无异常的情况下finally块中的语句都能执行……于是,矛盾就这样产生鸟。。。 在继续下去看答案之前,亲爱的读者们,你们觉得会是什么结果呢?finally会不会执行呢?请先思考一下再看答案。 既然在程序层看不出猫腻,那么我们不妨深入IL层去挖掘一下,上面代码的IL是这样子地: .try 请注意上面上面黄色部分代码,在catch块中,使用了leave.s这条命令来跳转到IL_0019这一行,而0019这一行正是ret命令,看起来……应该不会执行到finally才对~~难道说,从catch块就直接跳出了?! 我想该是时候去弄明白leave.s这条命令的作用了,看看Microsoft给出的定义:
没有为此指令指定任何堆栈转换行为。 leave.s 指令无条件将控制转移到传递的目标指令,这表示为距当前指令之后的指令的开始处的 1 字节有符号偏移量。 leave.s 指令类似于 br 指令,但它可用于退出 try、filter 或 catch 块,而一般分支指令只能在此类块中使用以在其内部转移控制。leave.s 指令清空计算堆栈并确保执行周围适当的 finally 块。 不能使用 leave.s 指令退出 finally 块。为了简化异常处理程序的代码生成,一个有效的方法是在 Catch 块的内部使用 leave.s 指令将控制转移到关联的 try 块中的任何指令。 如果指令有一个或多个前缀代码,则只能将控制转移到其中的第一个前缀。 OK,至此,一切明了了~~leave.s会确保finally块的执行,所以,即使在catch中使用了return语句想直接跳出,还是会先执行finally再return的 |
请发表评论