I was thinking about how VB.NET auto-initializes its variables if not explicitly written to before being read, something that C# does not allow. The simplest example would be something like this:
The equivalent in C# would not compile:
The compiler would complain about "Use of unassigned local variable 'j'" at the point where 'j.ToString()' is called.
So I wondered what the VB.NET code would look like when viewing the IL. I had expected to find an explicit assignment of 'j' to 0, presumably created by the VB.NET compiler. But I was surprised at what I found:
Basically, the 'int32 j' is not assigned a value before .ToString() is called. I had expected to see 'j' being set to zero via a 'ldc.i4.0' call followed by 'stloc.0' and then the rest of the routine would proceed as shown above.
That is, I had expected to see this:
So does the CLR itself zero out all variables? And therefore VB.NET is not really "doing anything", but instead is merely allowing the default behavior to occur, whereas C# is being more restrictive?
Or is there a CIL setting, attribute, or the like somewhere that determines whether unassigned memory should be zeroed out before use automatically? (A setting that VB.NET would be using, but not C#?)
Anyway, I was wondering if anyone here knew what was going on...
Mike
Code:
' VB.NET:
Public Sub MySub()
Dim j As Integer
MessageBox.Show(j.ToString)
End Sub
The equivalent in C# would not compile:
Code:
// C#:
public void MySub()
{
int j;
MessageBox.Show(j.ToString());
}
So I wondered what the VB.NET code would look like when viewing the IL. I had expected to find an explicit assignment of 'j' to 0, presumably created by the VB.NET compiler. But I was surprised at what I found:
Code:
.method public instance void MySub() cil managed
{
.maxstack 1
.locals init (
[0] int32 j)
L_0000: ldloca.s j
L_0002: call instance string [mscorlib]System.Int32::ToString()
L_0007: call valuetype [System.Windows.Forms]System.Windows.Forms
.DialogResult [System.Windows.Forms]System.Windows.Forms
.MessageBox::Show(string)
L_000c: pop
L_000d: ret
}
Basically, the 'int32 j' is not assigned a value before .ToString() is called. I had expected to see 'j' being set to zero via a 'ldc.i4.0' call followed by 'stloc.0' and then the rest of the routine would proceed as shown above.
That is, I had expected to see this:
Code:
.method public instance void MySub() cil managed
{
.maxstack 1
.locals init (
[0] int32 j)
L_0000: ldc.i4.0
L_0001: stloc.0
L_0002: ldloca.s j
L_0003: call instance string [mscorlib]System.Int32::ToString()
L_0004: call valuetype [System.Windows.Forms]System.Windows.Forms
.DialogResult [System.Windows.Forms]System.Windows.Forms
.MessageBox::Show(string)
L_0005: pop
L_0006: ret
}
Or is there a CIL setting, attribute, or the like somewhere that determines whether unassigned memory should be zeroed out before use automatically? (A setting that VB.NET would be using, but not C#?)
Anyway, I was wondering if anyone here knew what was going on...
Mike