Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When is a static variable created?

Tags:

vb.net

Let's say I have a static variable in a function:

Private Sub SomeFunction()
    Static staticVar As String = _myField.Value
End Sub

When, exactly, is the value from _myField assigned to staticVar? Upon the first call to the function? Instantiation of the enclosing class?

like image 409
Nathan Weir Avatar asked Aug 30 '12 14:08

Nathan Weir


People also ask

Where static variables are created?

The static variables are stored in the data segment of the memory. The data segment is a part of the virtual address space of a program. All the static variables that do not have an explicit initialization or are initialized to zero are stored in the uninitialized data segment( also known as the BSS segment).

When a static variable is created in Java?

When a variable is declared as static, then a single copy of the variable is created and shared among all objects at the class level. Static variables are, essentially, global variables. All instances of the class share the same static variable.

When should variables be static?

Static local variables are useful when we want to have only one instance of our object in the local scope, which means all calls to the function will share the same object. The same can also be achieved by using global variables or static member variables.

How many times is a static variable created and when?

A static variable declaration is only executed once, the first time the function is executed. A static variable is initialized only once (since this is part of the declaration process) and will be initialized to 0 unless the programmer designates otherwise.


2 Answers

The CLR has no support for this construct so the VB.NET compiler emulates it.

Creation first. The variable is lifted to a private field of the class with an unspeakable name that ensures no name collisions can occur. It will be an instance field if the variable is inside an instance method of the class. So will be created when an object of the class is created with the new operator. It will be a Shared field if the method is Shared or is part of a Module. So will be created in the loader heap by the jitter.

Assignment next, the much more involved operation. The language rule is that assignment occurs when code execution lands on the Dim statement for the first time. The term first time is a loaded one. There's an enormous amount of code generated by the compiler inside the method to ensure this is guaranteed. The kind of problems that need to be addressed are threading, recursion and exceptions.

The compiler creates another hidden helper field of type StaticLocalInitFlag at the same scope as the hidden variable field to keep track of initialization state for the variable. The first part of the injected code is a call to Monitor.Enter() to deal with threading. Same thing as SyncLock. The StaticLocalInitFlag serves as the locking object, note how it is a class and not just a Boolean.

Next, Try and Finally statements guard against exceptions. Inside the Try statement, the value of StaticLocalInitFlag.State is checked for 0. This protects against recursion on the same thread. State is then set to 2 to indicate that initialization code is running. Followed by the assignment. Next, State is checked again to see if it is still 2. If it is not then something went drastically wrong and an IncompleteInitialization exception is thrown.

The Finally block then sets the State to 1 to indicate that the variable is initialized. Followed by a call to Monitor.Leave().

Lots of code, 96 bytes of IL for just a simple variable. Use Static only if you don't worry about the cost.

like image 180
Hans Passant Avatar answered Nov 08 '22 00:11

Hans Passant


A Static variable is instantiated when it is assigned, obviously.

When that line is run, not before, not after.

Put a breakpoint on it and you'll see.

Static just means that the value will persist between calls.

Shared class/module members are instantiated the first time the class is accessed, before any Shared constructor and before the call, whether that is to the class constructor or some Shared method/property. I think this may be the origin of your confusion. Static local variables, like local statics in c# are not instantiated in this way.


Interesting information from Tim Schmelter, it appears the value is maintained internally using a hidden Shared class level variable that is instantiated like other Shared class level variables but always with the default value.

The effect observed by you the developer is unchanged, apart from some instantiation delay when the class is accessed. This delay should be undetectable in practice.

like image 31
5 revs Avatar answered Nov 07 '22 23:11

5 revs