Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

static field Initialization in debug and release build

Tags:

c#

I found static field initialization can behave differently. for the following code,

public class Class1
{
  public static void Main()
  {
    Console.WriteLine("Main");
    Test();
    Console.ReadLine();
  }

  public static void Test(){
    Console.WriteLine("Test");
    Singleton.Instance.DoSomething();
  }
}

public class Singleton
{
  private static Singleton sInstance = new Singleton();

  protected Singleton()
  {
    Console.WriteLine("Singleton Constructor");
  }

  public static Singleton Instance
  {
    get
    {
      return sInstance;
    }
  }

  public void DoSomething(){}
}

in the debug build, it will print

Main
Test
Singleton Constructor

while in release build, it will print

Main
Singleton Constructor
Test

I checked the IL code generated of these 2 builds, there are nearly the same.

I wonder how this happens? And if it is a kind of JIT optimization in the release build, what is the motivation?

like image 775
Fei Avatar asked May 27 '12 15:05

Fei


People also ask

What is static initialization in C#?

A static constructor is used to initialize any static data, or to perform a particular action that needs to be performed only once. It is called automatically before the first instance is created or any static members are referenced. C# Copy. class SimpleClass { // Static variable that must be initialized at run time.

Why static constructor is Parameterless in C#?

When a data member is shared among different instances it is imperative that data should be consistent among all the instances of the class. And also there is no way to call static constructor explicitly. Therefore the purpose of having a parameterized static constructor is useless.

Which constructor is called first in C# static or default?

Prerequisite: Constructors in C# Static constructors are used to initialize the static members of the class and are implicitly called before the creation of the first instance of the class. Non-static constructors are used to initialize the non-static members of the class.

Can we create static constructor in non-static class?

Also, you can have a static constructor in a static class or a non-static class. A static constructor is used to initialize the static members of a class. The static constructor of a class is invoked the first time a static member of the class is accessed.


2 Answers

It completely depends on implementation when static initializers will execute . So the order could be different. But if you provide a static constructor those static initializers will always execute earlier. Hence the output will be in a consistent order.

From MSDN

The static field variable initializers of a class correspond to a sequence of assignments that are executed in the textual order in which they appear in the class declaration. If a static constructor (Section 10.11) exists in the class, execution of the static field initializers occurs immediately prior to executing that static constructor. Otherwise, the static field initializers are executed at an implementation-dependent time prior to the first use of a static field of that class.

Add a static constructor in the Singleton class

static Singleton() { }
like image 120
Shiplu Mokaddim Avatar answered Sep 22 '22 10:09

Shiplu Mokaddim


I repro for the x86 jitter in the release build. This is by design, there is no guaranteed exact moment that the static class constructor runs, the only requirement is that it happens before any other methods in the class run. So the optimizer is permitted to rearrange code if that produces more efficient code. It does, it moves the cctor call all the way back to the Main() method. With the advantage that it now has more opportunities to optimize the remaining code.

In general, you want to avoid writing code in initialization expressions that has observable side-effects.

like image 45
Hans Passant Avatar answered Sep 21 '22 10:09

Hans Passant