I have a static library which is generated from many cpp files on linux using g++. one header file contains a class which implements factory pattern
pseudo code in the header file as below
class Factory
{
public:
static Factory& instance();
Base * create(const std::string& name);
template<class T>
void register_class(const std::string& name);
}
template <class T>
class FactoryRegister
{
public:
FactoryRegister(const std::string& name)
{
Factory::instance().register_class<T>(name);
}
}
cpp file for Factory has the implementations. in another cpp file Derive.cpp, there is a class that I want to register into Factory. and I defined a global variable to do this. code as below
FactoryRegister<Derive> g_register_derive("derive");
all these files are compiled into one static library and is linked to one executable.
my understanding is that as the g_register_derive is not referenced by any code, it shouldn't be linked into the executable unless whole-archive option is provided.
the strange part is that if I put g_register_derive in Derive.cpp, it's true that this symbol is not linked into the executable. but if I put g_register_derive in Factory.cpp, it got linked into executable.
I used nm to verify the result, and there is also a line of code calls Factory::instance().create("Derive")
which can also be used to check if g_register_derive is linked or not.
and of course if I provided whole-archive option, g_register_derive will always be linked into the executable.