Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Static member variable not being initialized in Release - Compiler/clr bug?

Tags:

c#

clr

.net-4.0

Expected output & output I get in debug mode, and release mode under VS2010, .NET 4.0:

bar construct
main

Output in release mode not under the VS2010 debugger, and under WinDbg:

main

Program does not exhibit this behavior on VS2005, .NET 2.0

using System;

namespace static_init
{
    public class bar
    {
        public bar()
        {
            Console.WriteLine("bar construct");
        }
    }

    class Program
    {
        public static bar blah = new bar();

        static void Main(string[] args)
        {
            Console.WriteLine("main");
            Console.ReadLine();
        }
    }
}

Probably related: Static constructor can run after the non-static constructor. Is this a compiler bug?

Update

In my actual code constructor bar() initializes some interop code with C++ (unmanaged). It needs to happen before anything else in this library - is there any way to ensure that without putting in an init() function that touches all of the statics (with side effects that aren't externally referenced) in the library?

Note for future searchers: I'm using SWIG, and this is an assumption that they made in their wrapper generation code. SWIGStringHelper is the current offender, there may be more though.

Conclusion

Update to version 2.0 of SWIG, it puts in the static constructor as needed by newer version of .NET.

like image 295
Zac Avatar asked Aug 26 '10 22:08

Zac


1 Answers

It's probably getting optimized out because you don't use it.

It also isn't a compiler bug, it's in the language spec.

17.4.5.1 Static field initialization

The static field variable initializers of a class declaration 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 (§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

Since you never use a static field of the Program class, the static initializer isn't guaranteed to run (though it could...the 'implementation-dependent time' above)

Update
You can accomplish what you want by making Program have a static constructor.

static Program (){} or possibly by accessing another (possibly dummy) static variable

like image 79
µBio Avatar answered Oct 05 '22 22:10

µBio