静态初始化器在库中时被优化掉

Dev*_*lus 5 c++ gcc

我有一个静态调用初始化例程的函数。这是插件系统所需要的,其中插件要么是动态加载的(工作正常),要么也可以是静态链接的。由于主应用程序不知道静态插件,它必须注册自己,以便主应用程序知道它(就像它是动态加载的插件一样)。

现在的问题是初始化从未被调用。但是,当我添加一个虚拟函数并从主应用程序调用它时,初始化程序突然被调用。所以这在我看来好像初始化是从 gcc 中“优化”的。

static bool registerPlugins(void)
{
    std::cout << "Registering CSV static plugin ... " << std::endl;
    PluginManager::registerStaticPlugin(&PluginInfo);

    return true;
}
static bool gCSVRegistered = registerPlugins();
Run Code Online (Sandbox Code Playgroud)

永远不会打印文本“正在注册...”,但添加了虚拟功能

void helper(void)
{
    std::cout << "Registered: "  << gCSVRegistered << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

...并从主应用程序中调用它,然后打印所有期望的文本。

那么我怎样才能强制静态初始化器不被扔掉???

我正在将 Mingw32 与 gcc 4.9.2 一起使用(仅供记录:))。

重要更新:相关代码在静态库中。在这种情况下,它不会被触发,只有当模块直接链接到主应用程序时才会调用初始化器。

南昌

main.cpp:

#include <iostream>

const char *gData = NULL;

int main()
{
    if(gData)
        std::cout << "Registration: " << gData << std::endl;
    else
        std::cout << "Registration: NULL" << std::endl;

    return 0;
}

void registered(const char *pData)
{
    gData = pData;
}
Run Code Online (Sandbox Code Playgroud)

static1.cpp

void registered(const char *pData);

static bool registration(void)
{
    registered("Static initializer 1");
    return true;
}

static bool reg = registration();
Run Code Online (Sandbox Code Playgroud)

static2.cpp

void registered(const char *pData);

static bool registration(void)
{
    registered("Static initializer 2");
    return true;
}

static bool reg = registration();
Run Code Online (Sandbox Code Playgroud)

static library: lib_main.cpp

void registered(const char *pData);

static bool registration(void)
{
    registered("Static initializer library");
    return true;
}

static bool reg = registration();
Run Code Online (Sandbox Code Playgroud)

Dev*_*lus 3

所以因为对这个问题的评论最终引导我走向了正确的方向。问题在于该函数位于静态库中,如果主应用程序中未使用该代码,则不会调用该代码,因为链接器甚至不会将代码添加到可执行文件中。

为了更详细的描述,我发现了这个问题: Static初始化和销毁​​静态库的全局变量不会发生在g ++中

为了强制调用代码,我必须将注册移动到肯定需要的模块中(从而被链接到),或者使用链接器选项-Wl,--whole-archive

ld 链接器问题:--whole-archive 选项