Search code examples
c++staticconstructorogre3d

Constructor called twice on static std::map


I am certain I have done something wrong to make this happen. I am using a library that declares a map statically in a way that seems to make sense.

In the header, in a class called Codec:

    typedef map< String, Codec* >::type CodecList; 
    static CodecList msMapCodecs;

In the cpp file:

    map< String, Codec * >::type Codec::msMapCodecs;

When I put a breakpoint on the line in the cpp file I have seen that it calls this in a stack frame called "__static_initialization_and_destruction_0" and if I step into it I can see it call the constructor for this map before main is reached. Just after main starts I insert some entries via function calls of the library API, then I notice the constructor is called a second time in a similar way to first.

What could cause this, or what and I misunderstanding that could confuse me enough to think this is happening? I have searched and I don't see an explicit calls to the constructor. I could not duplicate this in a minimal test case. I know that providing an exact answer is not possible, but anything that will point me a good direction would be appreciated.

If it matters I am using gcc 4.6.3 on Ubuntu 12.04. x64


Solution

  • This was a visibility/symbol version issue problem. There are a variety of ways to have corrected this. Since this only exists with this compiler on this OS I decided to alter the header file slightly and maintain the changes myself. I will let creators of the library know in case they want to incorporate this change.

    More details on symbol visibility can be found at: http://gcc.gnu.org/wiki/Visibility

    Here are the changes I made to the code:

    #if __GNUC__ >= 4
        // This block will be included only will the compiler
        #define DLL_LOCAL  __attribute__ ((visibility ("hidden")))
    #else
        #define DLL_LOCAL
    #endif
    
    // <- Some details omitted here
    
    typedef map< String, Codec* >::type CodecList; 
    DLL_LOCAL static CodecList msMapCodecs;