April 12, 2005

Visual Basic .NET Gotcha #1

Remember how we were all told that the .NET Framework guaranteed that our declared variables would be set to their default values on declaration? Well, there is at least one instance where that won't happen.

Let's look at the following code:
    Sub Main()

For i As Integer = 1 To 10
Dim j As Integer
j += 1
Console.WriteLine(j)
Next

End Sub
The variable j leaves scope at the end of each iteration, but this code does not print 10 lines containing "1". It counts from 1 to 10.

Why? To save the time of reallocating and reinitializing the variable each loop, the Visual Basic compiler switches the code around a bit so you get this:
    Sub Main()

Dim j As Integer

For i As Integer = 1 To 10
j += 1
Console.WriteLine(j)
Next

End Sub
The solution is that any variable that you declare inside of your loop needs to be explicitly initialized, like so:
    Sub Main()

For i As Integer = 1 To 10
Dim j As Integer = 0
j += 1
Console.WriteLine(j)
Next

End Sub
The above snippet will work as expected: 10 lines, each containing a "1".

The worst kind of "gotcha" is an undocumented "gotcha..."

1 comment:

John Morales said...

Michael,

IIRC, your first example does exactly what the language specification says it is supposed to do. The only variable that is scoped within the For...Next loop is i. Any variable declarations within a looping structure are pulled out of the loop and declared before the loop; just what the compiler did in your first example. It is bad code to declare variables within a looping structure that the compiler "fixes" for you.