李威 さぽている

小说翻译,日语相关转移至http://blog.hjenglish.com/liwei

try-finally,return的执行顺序小析~

项目中一个try-finally语句中有return,不明白执行的顺序,于是搜索了一番。
http://www.usdprofits.com/finally-return-t344073.htm
虽然回答的是JAVA的,但也有借鉴作用。
===================================================
首先执行finally,然后才执行return;
如果finally里面有return,try中的return不会再执行;
如果try中有了异常,return也不执行;
ps:异常实际上也是一种返回值
===================================================
http://fanyaojun.bokee.com/126611.html
有一段程序显示先执行try,再finally最后return。
http://www.blog.edu.cn/user1/16293/archives/2006/1248335.shtml
分析了IL代码,指出了比较根本性的原因。

但我写了一个程序却出现了一个怪问题。
主程序清单如下:

static   void  Main( string [] args)
        
{
            Console.WriteLine(TestFR().ToString());
        }


        
static   int  TestFR()
        
{
            
int  i  =   1 ;
            
try
            
{
                i 
=   2 ;
                
return  i;
            }

            
            
finally
            
{
                i 
=   3 ;
                Console.WriteLine(
" finally block executed. " );
            }

        }



它显示的是什么呢?
按照前面讲的,先写“finally block executed.”再输出3
可实验结果却是
finally block executed.
2

怎么回事?我也来分析下IL代码~~以下是TestFR()的~

.method  private  hidebysig  static  int32  TestFR() cil managed
{
  
//  コード サイズ       29 (0x1d)
  .maxstack   1
  .locals init ([
0 ] int32 i,
           [
1 ] int32 CS$ 1 $ 0000 )
  IL_0000:  nop
  IL_0001:  ldc.i4.
1
  IL_0002:  stloc.
0
  .
try
  
{
    IL_0003:  nop
    IL_0004:  ldc.i4.
2
    IL_0005:  stloc.
0
    IL_0006:  ldloc.
0
    IL_0007:  stloc.
1
    IL_0008:  leave.s    IL_001a
  }
   //  end .try
   finally
  
{
    IL_000a:  nop
    IL_000b:  ldc.i4.
3
    IL_000c:  stloc.
0
    IL_000d:  ldstr      
" finally block executed. "
    IL_0012:  call       
void  [mscorlib]System.Console::WriteLine( string )
    IL_0017:  nop
    IL_0018:  nop
    IL_0019:  endfinally
  }
   //  end handler
  IL_001a:  nop
  IL_001b:  ldloc.
1
  IL_001c:  ret
}
  //  end of method Program::TestFR


这里涉及到3个存储区:堆栈,局部变量区,计算堆栈。至于它们的区别,我不是很清楚,有人知道的话,告诉我吧。
01句(以下同样只简称后两位IL_0001)将数字1放到堆栈,02句弹出到局部变量0中,对应的语句就是i = 1;try中几句是将数字2放到堆栈,再弹出到局部变量0,06句将局部变量0加载到计算堆栈。07句将其弹出到局部变量1,因为只有计算堆栈里有数据,所以弹的是计算堆栈的值。08跳到1a去,但不能跳过finally句。
finally句中将数字3放到局部变量0中,再显示字符串。
而后,关键的地方就到了。1b句将局部变量1加载到计算堆栈,再由ret返回值。
这里,为什么将局部变量1也就是数字2返回呢?不可理解呀~

posted on 2006-09-13 19:06 李威 阅读(3818) 评论(1)  编辑  收藏

评论

# re: try-finally,return的执行顺序小析~ 2006-09-14 18:40 李威

问题似乎解决了~~
将那个程序作些小的修改(只写修改部分了)
=================================
int i = 1 ;
int b;
try
{
i = 2 ;
return b = i;
}
==================================
这样,在return处设断点就可以看明白了~return后面的语句在finally之前就执行了,b=2;也就是返回值已经确定,保存在特定区域了。finally的语句执行后b仍等于2,对返回值不起作用了。  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航: