M
Mark Walsh
The following is an explanation of a bug that exists in the VB.NET compiler.
I've tried to report it to Microsoft, but they've made it so difficult I've
given up:
MSDN help states that variables are initialised when they are created. This
seems to be true for the following code which produces "1","2","3","4","5".
(ie the variable is created when a procedure is entered and not when
for-loop is entered)
For i = 1 To 5
Dim x As Integer
x += 1
MsgBox(x.ToString)
Next
However, this is INCONSISTENT with the following code:
For i = 1 To 5
Dim x As Integer = 0
x += 1
MsgBox(x.ToString)
Next
which displays "1","1","1","1","1" implying that the variable is re-created
(if I believe the help) and consequently re-initialised each time the loop
iterates (ie: when it comes into scope, not when it is created)
If you disassemble a piece of code you will see that variables are created
when the PROCEDURE is entered NOT when a block (eg a "for loop") is entered:
For Example, the following code:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Dim i As Integer
Dim W As Integer = 2
Dim A As Integer = 3
Dim C As Integer = 4
Dim R As Integer = 5
Dim T As Integer = 6
Dim F As Integer = 7
For i = 1 To 5
Dim x1 As Integer = 0
Dim x2 As Integer = 0
Dim x3 As Integer = 0
Dim x4 As Integer = 0
Dim x5 As Integer = 0
Dim x6 As Integer = 0
x1 += 1
Next
End Sub
Disassembles as:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
00000000 push ebp
00000001 mov ebp,esp
00000003 sub esp,3Ch
00000006 push edi
00000007 push esi
00000008 push ebx
00000009 mov dword ptr [ebp-4],ecx
0000000c mov dword ptr [ebp-8],edx
0000000f xor ebx,ebx
00000011 mov dword ptr [ebp-10h],0
00000018 mov dword ptr [ebp-14h],0
0000001f xor esi,esi
00000021 mov dword ptr [ebp-1Ch],0
00000028 mov dword ptr [ebp-20h],0
0000002f mov dword ptr [ebp-24h],0
00000036 xor edi,edi
00000038 mov dword ptr [ebp-2Ch],0
0000003f mov dword ptr [ebp-30h],0
00000046 mov dword ptr [ebp-34h],0
0000004d mov dword ptr [ebp-38h],0
00000054 mov dword ptr [ebp-3Ch],0
0000005b nop
Dim W As Integer = 2
0000005c mov dword ptr [ebp-24h],2
Dim A As Integer = 3
00000063 mov ebx,3
Dim C As Integer = 4
00000068 mov dword ptr [ebp-10h],4
Dim R As Integer = 5
0000006f mov dword ptr [ebp-1Ch],5
Dim T As Integer = 6
00000076 mov dword ptr [ebp-20h],6
Dim F As Integer = 7
0000007d mov dword ptr [ebp-14h],7
For i = 1 To 5
00000084 mov esi,1
Dim x1 As Integer = 0
00000089 xor edi,edi
Dim x2 As Integer = 0
0000008b mov dword ptr [ebp-2Ch],0
Dim x3 As Integer = 0
00000092 mov dword ptr [ebp-30h],0
Dim x4 As Integer = 0
00000099 mov dword ptr [ebp-34h],0
Dim x5 As Integer = 0
000000a0 mov dword ptr [ebp-38h],0
Dim x6 As Integer = 0
000000a7 mov dword ptr [ebp-3Ch],0
x1 += 1
000000ae add edi,1
000000b1 jno 000000BA
000000b3 xor ecx,ecx
000000b5 call 7847D2B4
Next
000000ba nop
000000bb add esi,1
000000be jno 000000C7
000000c0 xor ecx,ecx
000000c2 call 7847D2B4
000000c7 cmp esi,5
000000ca jle 00000089
End Sub
Notice that on line 00000092 for example (the code for Dim x3 As Integer =
0) that it is assigning zero to an address pointed to by register ebp-30h.
In other words the variable has already been created on the stack when the
procedure was entered, not when the loop is entered. This assignment is at
complete odds with the help which says that initialisation happens when a
variable is created.
The above behaviour is also inconsistent with the following code:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Static x As Integer = 3
Dim i As Integer
For i = 1 To 5
x += 1
Next
MsgBox(x.ToString)
End Sub
The above piece of code displays '8' the first time the procedure is
entered, and 13 the second time the procedure is entered. STATIC X is only
created once (the first
time the procedure is entered) and initialised once, when the variable is
created. Not every time the variable comes into scope.
"this behaviour is by design" ... I hope not, it's a shocker.
Mark (KAZ technology services, Australia).
I've tried to report it to Microsoft, but they've made it so difficult I've
given up:
MSDN help states that variables are initialised when they are created. This
seems to be true for the following code which produces "1","2","3","4","5".
(ie the variable is created when a procedure is entered and not when
for-loop is entered)
For i = 1 To 5
Dim x As Integer
x += 1
MsgBox(x.ToString)
Next
However, this is INCONSISTENT with the following code:
For i = 1 To 5
Dim x As Integer = 0
x += 1
MsgBox(x.ToString)
Next
which displays "1","1","1","1","1" implying that the variable is re-created
(if I believe the help) and consequently re-initialised each time the loop
iterates (ie: when it comes into scope, not when it is created)
If you disassemble a piece of code you will see that variables are created
when the PROCEDURE is entered NOT when a block (eg a "for loop") is entered:
For Example, the following code:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Dim i As Integer
Dim W As Integer = 2
Dim A As Integer = 3
Dim C As Integer = 4
Dim R As Integer = 5
Dim T As Integer = 6
Dim F As Integer = 7
For i = 1 To 5
Dim x1 As Integer = 0
Dim x2 As Integer = 0
Dim x3 As Integer = 0
Dim x4 As Integer = 0
Dim x5 As Integer = 0
Dim x6 As Integer = 0
x1 += 1
Next
End Sub
Disassembles as:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
00000000 push ebp
00000001 mov ebp,esp
00000003 sub esp,3Ch
00000006 push edi
00000007 push esi
00000008 push ebx
00000009 mov dword ptr [ebp-4],ecx
0000000c mov dword ptr [ebp-8],edx
0000000f xor ebx,ebx
00000011 mov dword ptr [ebp-10h],0
00000018 mov dword ptr [ebp-14h],0
0000001f xor esi,esi
00000021 mov dword ptr [ebp-1Ch],0
00000028 mov dword ptr [ebp-20h],0
0000002f mov dword ptr [ebp-24h],0
00000036 xor edi,edi
00000038 mov dword ptr [ebp-2Ch],0
0000003f mov dword ptr [ebp-30h],0
00000046 mov dword ptr [ebp-34h],0
0000004d mov dword ptr [ebp-38h],0
00000054 mov dword ptr [ebp-3Ch],0
0000005b nop
Dim W As Integer = 2
0000005c mov dword ptr [ebp-24h],2
Dim A As Integer = 3
00000063 mov ebx,3
Dim C As Integer = 4
00000068 mov dword ptr [ebp-10h],4
Dim R As Integer = 5
0000006f mov dword ptr [ebp-1Ch],5
Dim T As Integer = 6
00000076 mov dword ptr [ebp-20h],6
Dim F As Integer = 7
0000007d mov dword ptr [ebp-14h],7
For i = 1 To 5
00000084 mov esi,1
Dim x1 As Integer = 0
00000089 xor edi,edi
Dim x2 As Integer = 0
0000008b mov dword ptr [ebp-2Ch],0
Dim x3 As Integer = 0
00000092 mov dword ptr [ebp-30h],0
Dim x4 As Integer = 0
00000099 mov dword ptr [ebp-34h],0
Dim x5 As Integer = 0
000000a0 mov dword ptr [ebp-38h],0
Dim x6 As Integer = 0
000000a7 mov dword ptr [ebp-3Ch],0
x1 += 1
000000ae add edi,1
000000b1 jno 000000BA
000000b3 xor ecx,ecx
000000b5 call 7847D2B4
Next
000000ba nop
000000bb add esi,1
000000be jno 000000C7
000000c0 xor ecx,ecx
000000c2 call 7847D2B4
000000c7 cmp esi,5
000000ca jle 00000089
End Sub
Notice that on line 00000092 for example (the code for Dim x3 As Integer =
0) that it is assigning zero to an address pointed to by register ebp-30h.
In other words the variable has already been created on the stack when the
procedure was entered, not when the loop is entered. This assignment is at
complete odds with the help which says that initialisation happens when a
variable is created.
The above behaviour is also inconsistent with the following code:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Static x As Integer = 3
Dim i As Integer
For i = 1 To 5
x += 1
Next
MsgBox(x.ToString)
End Sub
The above piece of code displays '8' the first time the procedure is
entered, and 13 the second time the procedure is entered. STATIC X is only
created once (the first
time the procedure is entered) and initialised once, when the variable is
created. Not every time the variable comes into scope.
"this behaviour is by design" ... I hope not, it's a shocker.
Mark (KAZ technology services, Australia).