If I look at the IL that is created in Linqpad for the two following code snippets, I wonder what happens here.
In c#
int i = 42;
results in the following IL code
IL_0000: ret
whereas in VB
Dim i As Integer = 42
it is
IL_0000: ldc.i4.s 2A
IL_0002: stloc.0
Apparently, the c# compiler understands the the value is never used and thus simply returns nothing. In VB.NET the actual code is translated.
Is that due to differences in compiler optimization or is there anything else at work?
Update: Just to clarify this - I just enter this one line into LinqPad and look at the IL it creates (most definitely by running the respective compiler). There is no program.
C is a structured, procedural programming language that has been widely used both for operating systems and applications and that has had a wide following in the academic community. Many versions of UNIX-based operating systems are written in C.
Because C comes after B The reason why the language was named “C” by its creator was that it came after B language. Back then, Bell Labs already had a programming language called “B” at their disposal.
It is used for preprocessor directives (#include, #if, #else, #elif, #endif, #define, #undef, #error, #ifdef, #ifndef, # (null directive), #pragma) as well as the stringizing operator '#' and the token pasting operator '##'.
C exists everywhere in the modern world. A lot of applications, including Microsoft Windows, run on C. Even Python, one of the most popular languages, was built on C. Modern applications add new features implemented using high-level languages, but a lot of their existing functionalities use C.
Taking away the linqpad question, I ran vbc
and csc
with /optimize+ /debug-
on these programs:
Module f
Public Sub Main()
Dim i As Integer = 42
End Sub
End Module
and
public static class f
{
public static void Main()
{
int i = 42;
}
}
and got these CIL results from ILDASM:
For the 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
For the C#:
.method public hidebysig static void Main() cil managed
{
.entrypoint
// Code size 1 (0x1)
.maxstack 8
IL_0000: ret
} // end of method f::Main
So, yes, at least in this respect csc
is 'smarter' than vbc
. But I bet the JITter would remove any difference at execution time.
edit
I checked, and actually the executed native code is different, at least on my system. I put in Console.ReadLine()
calls in both to give me a chance to attach a debugger, and I got these disassemblies:
From the 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
From the 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
Now, my assembley is pretty much non-existent, but even I can see that
mov dword ptr [rsp+20h],2Ah
in the from-VB refers to a constant value of hex 2A
, which is 42 decimal. So there you go, it does execute more instructions in the end.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With