more on Static local variables

Posted Sun, Aug 20 2006 2:43 by bill
In my earlier post, I showed how Static local variables in VB are basically local variables that get promoted to class level fields.   What I didn't mention was the way initializers are handled on Static variables.  Take for example if I modified the code from the previous post, to include an initializer for the variable i
 
Class foo
 
   Public Sub bar()
      Static i As Int32 = 100
      i += 1
      Debug.Print(" i : " & i)
   End Sub
 
End Class
 
 
Module Module1
 
   Sub Main()
      Dim f As New foo
      For j As Int32 = 1 To 100
         f.bar()
      Next
   End Sub
 
End Module
 
Now the output would be 101 to 200. 
 
If However I wrote bar as :
  Public Sub bar()
      Static i As Int32
      i = 100
      i += 1
      Debug.Print(" i : " & i)
   End Sub
then the output would always be 101
 
The simplest way to understand this is to think of the Static variable getting promoted to class level field.  when this happens, the initialization line is promoted in it's entirety. 
 
So the first example really becomes:
 
Class foo
 
   Private i As Int32 = 100
 
   Public Sub bar()
      i += 1
      Debug.Print(" i : " & i)
   End Sub
 
End Class
 
although the field is not named i anymore in the real world, the above example is basically what happens. 
 
The second example becomes:
 
Class foo
 
   Private i As Int32
 
   Public Sub bar()
      i = 100
      i += 1
      Debug.Print(" i : " & i)
   End Sub
 
End Class
 
It's pretty simple once you look at it that way I think. :)
 
Oh, and try not to confuse this with the initialization rules for variables declared inside loop structures, as that's kind of the opposite. There the initialization code get's called on every loop.  Here on the other hand you can see the initialization of a Static variable is only called once, as that variable and it's initialization all gets promoted to a field. 
 
With loops, a variable declared inside the loop get's promoted to method level outside of all loop blocks (stack is allocated with the method), unless of course it's declared as Static then it gets promoted to a field.  Consider the following examples:
 
   Public Sub bar()
      For x As Int32 = 1 To 10
         Dim i As Int32 = 100
         i += 1
         Debug.Print(" i : " & i)
      Next
   End Sub
 
   Public Sub bar()
      For x As Int32 = 1 To 10
         Static i As Int32 = 100
         i += 1
         Debug.Print(" i : " & i)
      Next
   End Sub
 
If you guessed the first example prints out 101 all the time whereas the second one prints out an incrementing series from 101, e.g. {101, 102, 103, 104, 105, ……,111,112, ….}, then you guessed right :)  So just to see if I can confuse you some, can you guess what this code does :
   Public Sub bar()
      For x As Int32 = 1 To 10
         Dim i As Int32
         i += 1
         Debug.Print(" i : " & i)
      Next
   End Sub
 
If you guessed a series 1 to 10, you're doing well :)
 
And this one ?:
 
   Public Sub bar()
      For x As Int32 = 1 To 10
         Dim i As Int32 = 0
         i += 1
         Debug.Print(" i : " & i)
      Next
   End Sub
 
If you guessed it always prints out 1's, you've got this sucker nailed :)
 
That's about as complex as it gets :) 
(I threw the stuff in about loops just to make it a bit more interesting <g>)
 
Filed under: