11

如果我查看在 Linqpad 中为以下两个代码片段创建的 IL,我想知道这里会发生什么。

在c#中

int i = 42;

产生以下 IL 代码

IL_0000:  ret

而在VB中

Dim i As Integer = 42

这是

IL_0000:  ldc.i4.s    2A 
IL_0002:  stloc.0  

显然,c# 编译器理解该值从未使用过,因此根本不返回任何内容。在 VB.NET 中,实际代码被翻译。

这是由于编译器优化的差异还是有其他原因?

更新:只是为了澄清这一点-我只是将这一行输入到 LinqPad 中并查看它创建的 IL(最肯定是通过运行相应的编译器)。没有程序

4

2 回答 2

10

带走 linqpad 问题,我在这些程序上运行vbccsc使用:/optimize+ /debug-

Module f

Public Sub Main()
    Dim i As Integer = 42
End Sub

End Module

public static class f
{

public static void Main()
{
    int i = 42;
}

}

并从 ILDASM 获得这些 CIL 结果:

对于 VB:

.method public static void  Main() cil managed
{
  .entrypoint
  .custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 ) 
  // Code size       4 (0x4)
  .maxstack  1
  .locals init (int32 V_0)
  IL_0000:  ldc.i4.s   42
  IL_0002:  stloc.0
  IL_0003:  ret
} // end of method f::Main

对于 C#:

.method public hidebysig static void  Main() cil managed
{
  .entrypoint
  // Code size       1 (0x1)
  .maxstack  8
  IL_0000:  ret
} // end of method f::Main

所以,的,至少在这方面cscvbc. 但我敢打赌 JITter 会在执行时消除任何差异。

编辑

我检查了一下,实际上执行的本机代码不同的,至少在我的系统上是不同的。我Console.ReadLine()在两者中都打了电话,让我有机会附加一个调试器,我得到了这些反汇编:

来自VB:

00000000  sub         rsp,38h 
00000004  mov         dword ptr [rsp+20h],0 
0000000c  mov         rax,7FF000434D8h 
00000016  mov         eax,dword ptr [rax] 
00000018  test        eax,eax 
0000001a  je          0000000000000021 
0000001c  call        FFFFFFFFE45BA230 
00000021  mov         dword ptr [rsp+20h],2Ah 
00000029  call        FFFFFFFFE26ABF20 
0000002e  mov         qword ptr [rsp+28h],rax 
00000033  nop 
00000034  jmp         0000000000000036 
00000036  add         rsp,38h 
0000003a  ret 

从 C#:

00000000  sub         rsp,38h 
00000004  mov         rax,7FF000534D8h 
0000000e  mov         eax,dword ptr [rax] 
00000010  test        eax,eax 
00000012  je          0000000000000019 
00000014  call        FFFFFFFFE45AA230 
00000019  call        FFFFFFFFE391BF20 
0000001e  mov         qword ptr [rsp+20h],rax 
00000023  nop 
00000024  jmp         0000000000000026 
00000026  add         rsp,38h 
0000002a  ret 

现在,我的组装几乎不存在,但即使我能看到

mov         dword ptr [rsp+20h],2Ah 

在 from-VB 中是指 hex 的常量值2A,即十进制的 42。所以你去吧,它最终执行更多的指令。

于 2012-02-09T11:10:34.223 回答
1

我认为在 C# 情况下,编译器会一步完成内存分配部分并保存 int 的值,而在 VB 情况下,DIM 语句是第一步,它只是分配内存,然后在第二步中保存值。DIM 是通用的,可与所有数据类型一起使用,因此在所有情况下它都可能是额外的一步。想法?

于 2012-02-09T11:29:13.067 回答