是否总是分配函数的默认返回变量?

时间:2015-01-21 14:28:23

标签: vb.net compiler-optimization

我对如何实现名称与函数相同的默认变量感兴趣。

  • 即使我没有使用它,Sum总是会被分配吗? (见case 1
  • 如果我选择另一个变量(Total中的CASE 3),是否使用了Sum

以下3个等效案例在编译时是否也相同?还是有些优于其他人?

' EQUIVALENT CASES

' CASE 1
Function Sum(a As Integer, b As Integer) As Integer
    Return a + b
End Function

' CASE 2
Function Sum(a As Integer, b As Integer) As Integer
    Sum = a + b
End Function

' CASE 3
Function Sum(a As Integer, b As Integer) As Integer
    Dim Total As Integer
    Total = a + b
    Return Total
End Function

当我在某处读到时,内联插入编译为小于32字节的函数。我想知道在某些情况下,我是否可能因为选择的符号而高于或低于限制。

2 个答案:

答案 0 :(得分:4)

我将你的函数分别重命名为Sum1,Sum2和Sum3,然后通过LinqPad运行它们。这是生成的IL:

Sum1:
IL_0000:  ldarg.1     
IL_0001:  ldarg.2     
IL_0002:  add.ovf     
IL_0003:  ret         

Sum2:
IL_0000:  ldarg.1     
IL_0001:  ldarg.2     
IL_0002:  add.ovf     
IL_0003:  stloc.0     // Sum2
IL_0004:  ldloc.0     // Sum2
IL_0005:  ret         

Sum3:
IL_0000:  ldarg.1     
IL_0001:  ldarg.2     
IL_0002:  add.ovf     
IL_0003:  stloc.1     // Total
IL_0004:  ldloc.1     // Total
IL_0005:  ret         

看起来Sum2和Sum3导致相同的IL。 Sum1似乎更有效,因为它将运算符的结果直接放到堆栈上。其他人必须将结果从堆栈中拉出到局部变量中,然后将其推回堆栈!

答案 1 :(得分:2)

我不是VB.NET专家,但我确实对C#有所了解。在C#中,这种代码是不允许的。您应始终return一个值,否则代码不会编译。

我想VB.NET在C#中用这样的东西来绕过这个:

T Sum = default(T);

...

return Sum;

默认值Sum,在int的情况下为0

根据这个逻辑,变量被分配,对于引用类型,这意味着将没有分配,因为它们默认为null

看着IL:

.method public static int32  Test() cil managed
{
  // Code size       3 (0x3)
  .maxstack  1
  .locals init ([0] int32 Test)
  IL_0000:  nop
  IL_0001:  ldloc.0
  IL_0002:  ret
} // end of method Module1::Test

来自Function

Function Test() As Integer

End Function

您将看到init,它初始化变量(分配它)和ldloc,这是一个获取变量值的调用,因此必须分配它。