Home Dashboard Directory Help
Search

C++/CLI class static constructor not called in release build by Jeremy Riley


Status: 

Closed
 as Fixed Help for as Fixed


7
0
Sign in
to vote
Type: Bug
ID: 611716
Opened: 10/8/2010 4:28:16 AM
Access Restriction: Public
1
Workaround(s)
view
6
User(s) can reproduce this bug

Description

I have a C++/CLI library project that contains a class with a static constructor. In a debug build the static constructor is (correctly) called before any other class methods are referenced. However in a release build it is never called.
Details
Sign in to post a comment.
Posted by ebyrob on 3/29/2012 at 11:21 AM
I see a vcredist_x86.exe dated 8/9/2011 on the download site, which was the most recent I could find. It still seems to exhibit this problem. Is there a later version of this package that fixes the issue?

What releases of which products have the fix?
Posted by Microsoft on 9/14/2011 at 11:48 AM
Hi: this issue has been fixed. The fix should show up in a future release of Visual C++.

Thank you for reporting the issue.

Jonathan Caves
Visual C++ Compiler Team
Posted by NicGorleer on 12/16/2010 at 2:24 AM
I have run into the same situation. The static constructor is not called in release mode outside IDE but it is called in release mode inside IDE and debug mode inside and outside IDE.

The static constructor was called correctly in .NET 2.0 generated by VS2008. Now in .NET 4.0 generated by VS2010 it is not called in release mode. I think this is a serious bug. I can't believe that you call this by design.
Posted by GenoMemphis on 11/11/2010 at 6:15 AM
Managed to get the static constructor to be called (release or debug, inside and outside the IDE)... I certainly don't understand why it works now and didn't before... it seems very touchy
Posted by GenoMemphis on 11/10/2010 at 5:40 AM
I have a very similar issue with VS2008. The Static Constructor is not getting called Outside the IDE. If I run the app inside the IDE, even in release mode, everything works as expected. I can't believe that this is by design; to work in the IDE but not outside.
Please Fix this!

Posted by Jeremy Riley on 11/1/2010 at 9:42 AM
Thank you for the explaination of what's happening. I'm not 100% sure how that translates to my situation where I have a class with only static member functions and private fields. As a workaround I've resorted to explicitly calling an initialisation function :-(. Maybe I'll translate the class to a singleton pattern at a later date...

I don't understand how the reasons given explain that this code worked as expected in a debug build and not in a release build (optimisation shouldn't change the meaning of the code). Additionally why did the move to VS2010 cause this to break? It was certainly working in VS2008 and I think VS2005.

In any case I would say that there is still something that needs to be done here. If it really is something that can't work properly in C++/CLI then the compiler should generate a warning when it encounters the code it can't compile correctly. This would at least stop others from wasting time understand what has broken.
Posted by ildjarn on 10/28/2010 at 1:52 PM
While the workaround is much appreciated, given that this is fundamentally broken in regards to /expected/ usability, shouldn't C++/CLI be addressed to allow creation of PreciseInit cctors rather than merely closing this as By Design?
Posted by Microsoft on 10/28/2010 at 1:20 PM
For a couple of (very wacky) reasons, this is by design.

First, the .Net Framework has 2 classes of static class constructors: BeforeFieldInit, and PreciseInit. BeforeFieldInit basically provide the promise that the static class constructor will be invoked at _some_ time before you access any static fields on the class. PreciseInit cctor's will be invoked immediately prior to first access of a static field, first invocation of a static method, or first invocation of a constructor. The unfortunate part of this is that there are still two loopholes: A constructorless class can have member methods invoked, and we _still_ don't have to invoke the cctor.

Secondly, it appears that C++/CLI doesn't allow you to ever create a preciseInit static class constructor. VB's are all precise, and C# is precise only when you declare one, but if you have static fields with initializers only, then the initializers are dumped into a BeforeFieldInit cctor. So, since you're never touching a static field, we aren't required to initialize the static class constructor. And C++ gives you no way to do anything differently, except by adding a static field, and touch it in your constructor :-(
Posted by Microsoft on 10/21/2010 at 2:57 PM
Hello Jeremy,

Thanks for this report. This indeed is a bug in our compiler and looks to be recently introduced bug. We're fixing it for the next release, and thank you very much for taking the time to report it.

Thanks,
Ulzii Luvsanbat
Windows C++ Team
Posted by Microsoft on 10/10/2010 at 8:51 PM
Thank you for reporting the issue.
We are routing this issue to the appropriate group within the Visual Studio Product Team for triage and resolution.These specialized experts will follow-up with your issue.
Posted by Microsoft on 10/8/2010 at 5:21 AM
Thank you for your feedback, we are currently reviewing the issue you have submitted. If this issue is urgent, please contact support directly(http://support.microsoft.com)
Sign in to post a workaround.
Posted by LatencyMachine on 12/13/2011 at 2:07 PM
1) Add a static class variable, such as ''static int s_iMicrosoftIssue_611716_Fix"
2) Add a regular instance ctor, if you don't already have one.
3) In the instance ctor, manipulate (maybe just read) the static variable, such as
CFoo::CFoo()
{
    if(s_iMicrosoftIssue_611716_Fix == 611716)
    {
        s_iMicrosoftIssue_611716_Fix = 0;
    }
}

What a pain!
File Name Submitted By Submitted On File Size  
StaticContructorTest.zip 10/8/2010 39 KB