• Create Account

### #ActualTrienco

Posted 04 April 2012 - 12:07 AM

One of my "favorite" issues that caused a lot of pain.

With VC++ you usually get away with actually referencing the variable somewhere (a dummy read in a destructor or whatever). GCC will actually delay it until the very first time the variable is actually accessed. So you can not rely on any side effects caused by the initialization to actually happen before main.

In short, trying something like this will usually not work:
bool classXisRegistered = registerClassX();


For VC++, you might get away with a simple reference somewhere
SomeClass::~SomeClass
{
bool dummy = classXisRegistered;
}


For GCC we actually had to create static global objects that would have the desired side effect in the constructor. And based on all the weird rules about how a compiler may optimize, I wouldn't rely on even this to work for absolutely every compiler.

template
class Registrator
{
public:
Registrator() { registerClass(); }
};

static const Registrator registerClassX;


By the way, this method still failed on another project, where this code was in a static lib that was used to build a dll. Somewhere along the way the linker still decided to drop it. They moved the entire code to be a direct part of the dll.

I played around and tested a few methods, which ended up in a somewhat convoluted test:
http://festini.devic...factorytest.zip

But I guess the easiest solution is to simply not rely on any side effects of global static variable initialization.

### #1Trienco

Posted 04 April 2012 - 12:05 AM

One of my "favorite" issues that caused a lot of pain.

With VC++ you usually get away with actually referencing the variable somewhere (a dummy read in a destructor or whatever). GCC will actually delay it until the very first time the variable is actually accessed. So you can not rely on any side effects caused by the initialization to actually happen before main.

In short, trying something like this will usually not work:
bool classXisRegistered = registerClassX();

For VC++, you might get away with a simple reference somewhere
SomeClass::~SomeClass
{
bool dummy = classXisRegistered;
}

For GCC we actually had to create static global objects that would have the desired side effect in the constructor. And based on all the weird rules about how a compiler may optimize, I wouldn't rely on even this to work for absolutely every compiler.

template<class X>
class Registrator
{
public:
Registrator() { registerClass<X>(); }
};

static const Registrator<X> registerClassX;


By the way, this method still failed on another project, where this code was in a static lib that was used to build a dll. Somewhere along the way the linker still decided to drop it. They moved the entire code to be a direct part of the dll.

I played around and tested a few methods, which ended up in a somewhat convoluted test:
http://festini.device-zero.de/factorytest.zip

But I guess the easiest solution is to simply not rely on any side effects of global static variable initialization.

PARTNERS