views:

70

answers:

4

I have a static library with the following code:

h file:

class Foo
{
public:
   Foo()
   {
       a = 4;
   }

   int a;
};


class Bar
{
public:
    static const Foo foo;
};

cpp file:

const Bar::foo = Foo();

My problem is that Bar::foo does not get initialized with a=4 until some time after main(). Before then a=0. I'm trying to access Bar::foo from a DLL which statically links to the library above. And my application links to that DLL but does not access Bar::foo directly. I'm using Visual Studio 2008.

Does anyone know what could be going on?

+5  A: 

$3.6.2/2- "Variables with static storage duration (3.7.1) or thread storage duration (3.7.2) shall be zero-initialized (8.5) before any other initialization takes place."

That explains why you get that value of 0

$3.6.2/4- "It is implementation-defined whether the dynamic initialization of a non-local variable with static storage duration is done before the first statement of main. If the initialization is deferred to some point in time after the first statement of main, it shall occur before the first use of any function or variable defined in the same translation unit as the variable to be initialized."

So what you are trying to do leads to undefined behavior as you are attempting to access a variable with static storage duration which has not yet been initialized as no code in that translation unit has been used as yet.

Chubsdad
Microsoft's implementation-defined behavior for the described scenario is that the initialization will have occurred before the DllMain()'s 'process attach' call is made.
Michael Burr
@Michael Burr: Oh Ok. That is a good piece of information. Thanks.
Chubsdad
A: 

Where and when exactly are you accessing Bar::foo? If it's statically linked into the DLL, then it should be initialized before DllMain()'s 'process attach' is called.

Are you setting a different entry point for the DLL than the default of _DllMainCRTStartup?

Michael Burr
I'm not using _DllMainCRTStartup; the DLL has no entry point per se, it's just a bunch of abstract class interfaces and implementations with a global extern C function to create the root class instance. It's done this way to be binary compatible. Do I need to define an entry point?
Matthew
`_DlMainCRTStartup` is part of the runtime library - you'll get it by default unless you do something specifically to override it.
Michael Burr
@Matthew - how is code in the DLL executing before `main()`? There must be something in `DllMain()`, an alternate DLL entry point, or some static init in your .exe must be calling into the DLL.
Michael Burr
There's no code executing in the DLL before main(). In the example I posted above the Foo constructor should be executing before main() as it's static, but it's not.
Matthew
A: 

Why don't you define a static method in bar which returns a reference to Foo, and in that static method, have a static instance of Foo, such that when it's first called (irrespective of where), it will get correctly initialised?

class Bar
{
  public:
    static Foo& foo()
    {
      static Foo inst;
      return inst;
    }
};
Nim
A: 

What code is noticing that Bar::foo isn't initialized yet? If it's another bit of static initialization in the DLL then you're probably running into C++'s static initialization order problem:

Michael Burr