Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is the order of static class initialization in C# deterministic?

I've done some searching and I think the following code is guaranteed to produce output:

B.X = 7  B.X = 0  A.X = 1  A = 1, B = 0 
static class B {     public static int X = 7;     static B() {         Console.WriteLine("B.X = " + X);         X = A.X;         Console.WriteLine("B.X = " + X);     } }  static class A {     public static int X = B.X + 1;     static A() {         Console.WriteLine("A.X = " + X);     } }  static class Program {     static void Main() {         Console.WriteLine("A = {0}, B = {1}", A.X, B.X);     } } 

I've run this numerous times and always get the output above the code section; I just wanted to verify will it change? Even if textually, class A and class B are re-arranged?

Is it guaranteed that the first use of a static object will trigger the initialization of its static members, followed by instantiating its static constructor? For this program, using A.X in main will trigger the initialization of A.X, which in turn initializes B.X, then B() and after finishing the initialization of A.X, will proceed to A(). Finally, Main() will output A.X and B.X`.

like image 445
Jess Avatar asked Sep 09 '10 22:09

Jess


People also ask

What is static initialization in C?

Static variables are initialized only once. Compiler persist the variable till the end of the program. Static variable can be defined inside or outside the function. They are local to the block. The default value of static variable is zero.

Are static variables initialized first?

Static variables are initialized only once , at the start of the execution. These variables will be initialized first, before the initialization of any instance variables. A single copy to be shared by all instances of the class. A static variable can be accessed directly by the class name and doesn't need any object.

What is the order of static variable initialization C++?

C++ guarantees that variables in a compilation unit (. cpp file) are initialised in order of declaration. For number of compilation units this rule works for each one separately (I mean static variables outside of classes). But, the order of initialization of variables, is undefined across different compilation units.

What is the order of initialization for data?

In the initializer list, the order of execution takes place according to the order of declaration of member variables. While using the initializer list for a class in C++, the order of declaration of member variables affects the output of the program. Program 1: C++


1 Answers

Straight from ECMA-334:

17.4.5.1: "If a static constructor (§17.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."

And:

17.11: The execution of a static constructor is triggered by the first of the following events to occur within an application domain:

  • An instance of the class is created.
  • Any of the static members of the class are referenced.

If a class contains the Main method (§10.1) in which execution begins, the static constructor for that class executes before the Main method is called. If a class contains any static fields with initializers, those initializers are executed in textual order immediately prior to executing the static constructor (§17.4.5).

So the order is:

  • A.X used, so static A() called.
  • A.X needs to be initialized, but it uses B.X, so static B() called.
  • B.X needs to be initialized, and it is initialized to 7. B.X = 7
  • All static fields of B are initialized, so static B() is called. X is printed ("7"), then it is set to A.X. A has already started being initialized, so we get the value of A.X, which is the default value ("when a class is initialized, all static fields in that class are first initialized to their default value"); B.X = 0, and is printed ("0").
  • Done initializing B, and the value of A.X is set to B.X+1. A.X = 1.
  • All static fields of A are initialized, so static A() is called. A.X is printed ("1").
  • Back in Main, the values of A.X and B.X are printed ("1", "0").

It actually comments upon this in the standard:

17.4.5: It is possible for static fields with variable initializers to be observed in their default value state. However, this is strongly discouraged as a matter of style.

like image 188
porges Avatar answered Sep 21 '22 11:09

porges