Это C# компилятор умнее компилятора VB.NET ?

если я посмотрю на IL, созданный в Linqpad для двух следующих фрагментов кода, мне интересно, что здесь происходит.

В 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, который он создает (наиболее определенно, запустив соответствующий компилятор). Там нет

2 ответов


убрав вопрос linqpad, я побежал vbc и csc С /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;
}

}

и получил эти результаты CIL от ILDASM:

для 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

и да по крайней мере в этом отношении csc "умнее", чем vbc. Но я уверен, что дрожание удалит любую разницу при исполнении время.

редактировать

я проверил, и на самом деле выполненный родной код is другой, по крайней мере, в моей системе. Я вставил 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 

в от-VB относится к постоянному значению hex 2A, что составляет 42 десятичных знака. Итак, вот вы идете, это тут выполните больше инструкций в конце.


Я думаю, что в случае C# компилятор выполняет часть выделения памяти и сохраняет значение int за один шаг, а в случае VB оператор DIM-это первый шаг, который просто выделяет память, а затем значение сохраняется на втором шаге. DIM является общим и используется со всеми типами данных, поэтому во всех случаях это может быть что-то вроде одного шага. Мысли?