静态初始化器在库中时会被优化 [英] static initializer is optimized away when it is in a library

查看:89
本文介绍了静态初始化器在库中时会被优化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个静态调用初始化例程的函数。这是插件系统动态加载(工作正常)或静态链接所需的插件系统所必需的。
由于静态插件并不为主应用程序所知,因此它必须自行注册,以便主应用程序知道它(就像它是一个动态加载的插件)。

现在的问题是,初始化永远不会被调用。但是,当我添加一个虚拟函数并从主应用程序调用它时,突然调用初始化程序。因此,这看起来好像initalization是远离gcc优化。

 静态布尔registerPlugins(void)
{
std :: cout<< 注册CSV静态插件...<<的std :: ENDL;
PluginManager :: registerStaticPlugin(& PluginInfo);

返回true;
}
static bool gCSVRegistered = registerPlugins();

不会打印注册...文本,但会添加虚拟功能

  void helper(void)
{
std :: cout<< 已注册:<< gCSVRegistered<<的std :: ENDL;
}

...并将其从主应用程序调用d,然后显示所有显示的文本打印出来。



那么我怎样才能强制静态的initalizer不会被扔掉???



I '使用Mingw32和gcc 4.9.2(仅用于记录:))。
$ b

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



SSCCE



main.cpp:

  #include <&的iostream GT; 

const char * gData = NULL;

int main()
{
if(gData)$ b $ std :: cout<< 注册:<< gData<<的std :: ENDL;
else
std :: cout<< 注册:NULL<<的std :: ENDL;

返回0;
}

void registered(const char * pData)
{
gData = pData;

static1.cpp

  void registered(const char * pData); 

static bool注册(void)
{
registered(Static initializer 1);
返回true;
}

static bool reg = registration();

static2.cpp

  void registered(const char * pData); 

static bool注册(void)
{
registered(Static initializer 2);
返回true;
}

static bool reg = registration();

静态库:lib_main.cpp

  void registered(const char * pData); 

static bool registration(void)
{
registered(Static initializer library);
返回true;
}

static bool reg = registration();


解决方案

我走向正确的方向。问题在于函数在静态库中,如果代码在主应用程序中没有被使用,则代码不会被调用,因为链接器甚至不会将代码添加到可执行文件中。



更详细的描述我发现这个问题:
静态初始化并破坏静态库的全局变量 g ++ 我必须将注册移动到一个肯定会需要的模块中(因此需要链接),或者使用链接器选项 -Wl, - whole-archive



ld链接器问题: - 整个归档选项


I have a function which calls an initialization routine statically. This is needed for a pluginsystem where the plugin is either dynamically loaded (which works fine) or can also be statically linked. Since the static plugin is not known to the main application it must register itself, so that the main app knows about it (just like it were a dynamically loaded plugin).

The problem now is that the initalization is never called. However, when I add a dummy function and call it from the main app, then the initializer is suddenly called. So this looks to me as if the initalization is "optimized" away from gcc.

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

    return true;
}
static bool gCSVRegistered = registerPlugins();

The text "Registering..." is never printed, but adding the dummy function

void helper(void)
{
    std::cout << "Registered: "  << gCSVRegistered << std::endl;
}

... and call it dfrom the main app, then all the exptected text is printed.

So how can I force the static initalizer to not get thrown away???

I'm using Mingw32 with gcc 4.9.2 (just for the record :)).

Important update: The relevant code is in a static library. In this case it doesn't get triggered, only when the module is linked directly to the main application the initalizer is called.

SSCCE

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;
}

static1.cpp

void registered(const char *pData);

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

static bool reg = registration();

static2.cpp

void registered(const char *pData);

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

static bool reg = registration();

static library: lib_main.cpp

void registered(const char *pData);

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

static bool reg = registration();

解决方案

So because of the comments on the question that finally led me into the right direction. The problem is that the function is in a static library and there the code is not called if it is not used in the main application, because the linker doesn't even add the code to the executable.

For a more detailed description I found this question: Static initialization and destruction of a static library's globals not happening with g++

In order to force the code being called, I have to either move the registration into a module that will be needed for sure (and thus gets linked in), or use the linker option -Wl,--whole-archive.

ld linker question: the --whole-archive option

这篇关于静态初始化器在库中时会被优化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆