Reputation: 806
Hi, all!
I'm developing winForm app on visual C++ (managed code). This app link native static library which contain block of code with static variable initialization:
class Cls
{
public:
static Cls* getInstance();
private:
static Cls _instance;
protected:
Cls(void);
};
#include "StdAfx.h"
#include "Cls.h"
Cls::Cls(void)
{
}
Cls Cls::_instance;
Cls* Cls::getInstance()
{
return &_instance;
}
I can link those library successfully, but when I try to use getInstance() method I get a run-time error before invoke main function of my app.
It's a third party library, so I cannot rebuild it or redefine Cls class on any other way.
App project uses /clr, entry point defined as main.
I tired to search a solution. I found that I must change entry point, but I don't know what value would be correct.
Please, help!
Upvotes: 1
Views: 848
Reputation: 254561
You're encountering the notorious "static initialisation order fiasco". When static objects are defined in two translation units, it's unspecified which is initialised first; so, if the constructor of one refers to the other, you could end up accessing it before it is initialised. The only guarantee is that they will all be initialised before main
begins.
The best solution is to avoid static objects. In particular, the Singleton anti-pattern that you are using is rather tricky to get right in C++, and is generally more trouble than it's worth.
If you really want to do this, then you can work around the fiasco by defining the static object inside a function:
Cls* Cls::getInstance()
{
static Cls _instance;
return &_instance;
}
This has the disadvantage that it introduces a "destruction order fiasco" (where it might not be safe to access from the destructor of another static object), and that it might not be thread-safe in some compilers (although it should be in any that claims C++11 compliance). If construction is thread-safe, then there will be a (small) runtime cost for each access, which might be a problem if you have extreme performance issues.
UPDATE: I've just noticed that you say that this evil class is outside your control and can't be changed. In that case, your options are:
main
has begun; in particular, follow my advice above and avoid any static objects of your own.Upvotes: 4