3

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

Alessandro Minoccheri
  • 35,521
  • 22
  • 122
  • 171
Sqeaky
  • 1,876
  • 3
  • 21
  • 40
  • `std::map` does not have a `type` member. – interjay Oct 04 '12 at 13:16
  • How do you link with this lib? Dynamically or statically? – Kiril Kirov Oct 04 '12 at 13:16
  • One call in initialization and one call, when use? Are you sure, that second call is call to default constructor (not call to copy c-tor)? – ForEveR Oct 04 '12 at 13:16
  • It is dynamically linked, and I copied the code verbatim. It must not be an std::map I will gets its actual type and post it. – Sqeaky Oct 04 '12 at 13:17
  • Both constructors took no arguments. – Sqeaky Oct 04 '12 at 13:18
  • 2
    As it's dynamically linked, you may want to check this question: http://stackoverflow.com/questions/2631918/main-program-and-shared-library-initializes-same-static-variable-in-static-ini . I have had the same issue - a constructor and destructor were called twice when linking dynamically (and just once, when static linking was used). I avoided this making the member non-static. But it was not the best solution (and it's not applicable for each situation) – Kiril Kirov Oct 04 '12 at 13:18
  • @LyubomirVasilev - "In the header, **in a class called Codec**" – Kiril Kirov Oct 04 '12 at 13:29
  • How is msMapCodecs ever populated? Neither the declaraion nor definition have an initialiser. – TheMathemagician Oct 04 '12 at 13:46
  • @TheMathemagician When I Step through it it does indeed populate with a seemingly valid set of image codecs. I think Kiril probably has the answer with this. – Sqeaky Oct 06 '12 at 19:30
  • @KirilKirov Thanks for the link that indirectly led me to the answer. – Sqeaky Oct 06 '12 at 20:58
  • @interjay They have a struct that wraps std::map that presents a type member that is a typedef to the type of the internal map. I think it makes writing templates easier. – Sqeaky Oct 06 '12 at 21:05

1 Answers1

0

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;
Sqeaky
  • 1,876
  • 3
  • 21
  • 40