2

I'm trying to understand how C++/Clang deals with static members in templates. To that end I defined a Singleton as follows:

template <class T> class Singleton {
public:
    static T* instance() {
        if (!m_instance)
            m_instance = new T;

        return m_instance;
    }

private:
    static T* m_instance;
};

template <class T> T* Singleton<T>::m_instance = nullptr;

This appears to work just fine provided my application is compiled as a single executable. When I start using plugins, i.e. dylibs opened with dlopen, I get multiple instances of the Singleton.

Normally I compile my application with -fvisiblity=hidden. If remove that option, meaning I use default visibility, then the Singletons behave properly. This led me to think I just need to export the symbol using __attribute__((visibility=default)) but this doesn't work.

What is going here, and what would the solution be?

Tim
  • 4,560
  • 2
  • 40
  • 64
  • 1
    That might help: http://stackoverflow.com/questions/398069/static-member-variable-in-template-with-multiple-dlls – PiotrNycz Sep 28 '15 at 21:04

1 Answers1

1

Similar to the suggestions in PiotrNycz's linked answer, the simplest solution for me was to add a visible explicit instantiation of template in a cpp file in the module where the type inheriting from Singleton was defined. A one-liner was sufficient:

template<> __attribute__((visibility=default)) MyType * Singleton<MyType>::m_instance = nullptr;

This will make the MyType instance of the Singleton template visible as an exported symbol in just one module. To avoid duplicate symbols the initialization of m_instance has to be removed from the definition of Singleton, i.e. delete this line:

template <class T> T* Singleton<T>::m_instance = nullptr;
Tim
  • 4,560
  • 2
  • 40
  • 64