Another article in this issue of the ASNA newsletter discusses AVR for .NET’s Shared()
keyword. In addition to Shared()
, there is another little-known, but valuable, variable-related keyword to consider, Static()
.
Let’s start with a quiz. What is the output of the following code?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
BegSr CallTest DclFld i Type(*Integer4) For From(i=1) To(3) Test() EndFor EndSr BegSr Test DclFld x Type(*Integer4) x = x + 1 Console.WriteLine(x) EndSr |
The output to the above code is 1 three times (you all should have gotten this one right!). This is because x
is declared local to the Test
subroutine and each time Test
goes out of scope, the value of x
is popped off the stack and it effectively disappears.
Let’s change the quiz slightly. What is the output of this code? Be careful with your answer! This one isn’t as easy.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
BegSr CallTest DclFld i Type(*Integer4) For From(i=1) To(3) Test() EndFor EndSr BegSr Test DclFld x Type(*Integer4) Static(*Yes) x = x + 1 Console.WriteLine(x) EndSr |
The output of the code above is 1,2,3. The Static(Yes)
causes the value of x
to persist across calls to the Test
subroutine. Don’t get confused here; Static(Yes)
doesn’t change the variable’s scope. The x
declared in Test()
is still only available inside Test()
; however its value persists. Static(*Yes)
changes the default rules for variable persistence. This is a handy little feature if you need a counter to persist itself across calls; it eliminates the need for what would probably have otherwise been a global variable.
Terminology confusion
Be aware that AVR and VB use Shared
to indicate that a variable is owned by a class, as opposed to non-shared members which are owned by class instances. AVR and VB also both use Static
to indicate that a variable’s value persists across routine calls.
Java and C# name things a little differently. In these languages, a variable owned by a class is a static
variable. Neither Java nor C# implement the concept of a variable that persists its value across routine calls.
Be aware of these terminology differences, especially if you are porting a C# example to AVR.