【发布时间】:2014-05-06 00:31:09
【问题描述】:
我正在尝试初始化全局地图
std::map<long, std::string> Global_ID_Mapper;
具有许多“init”类,例如:
struct AGlobalMapperInitializer
{
AGlobalMapperInitializer()
{
Global_ID_Mapper.insert( std::make_pair(1, "Value1") );
Global_ID_Mapper.insert( std::make_pair(2, "Value2") );
}
};
我想在应用程序启动期间自动填充地图。所以在我的一个 cpp 文件中,我只定义了那个“init”类的全局变量。
// AGlobalMapperInitializer.cpp
AGlobalMapperInitializer AGlobalMapperInitializer_Value;
Mapper 填充是 AGlobalMapperInitializer_Value 创建的副作用。
问题在于,如果 cpp 除了这个全局变量之外不包含任何内容,那么链接器显然会忽略 cpp。当我将一些有用的其他代码放入 cpp(或在某些非空 cpp 中定义全局初始化程序)时,将调用构造函数并填充全局映射器。但是如果 cpp 只包含没有在其他文件中引用的全局,则 cpp 被编译,obj 文件包含变量,但链接器在链接过程中没有提及它,它在 exe 中被遗漏。
我怎样才能坚持将cpp链接到exe? 是否有一些编译指示或虚拟代码可以放入 cpp 以使其不被忽略? 我使用 Visual Studio 2012。
【问题讨论】:
-
一种常见的替代方法是在第一次使用时初始化全局/单例。
-
您可以 (Dll) 导出整个类 AGlobalMapperInitializer 并使全局成为该类的静态成员,或者在标头中将全局声明为 extern (Dll) 导出到类外部。 (否则全局是翻译单元中的局部并优化出来)
-
链接器会丢弃所有未引用的对象。除了声明不应导出的导出之外,您还可以在任何函数中引用它。请注意编译器无法优化此引用,例如
main() { printf("", &AGlobalMapperInitializer_Value)); } -
@harper 你的方法有效,我发现了。问题是我不想污染不相关的代码。
-
@MooseBoys 这不是我的情况。单例/全局
Global_ID_Mapper不知道他的初始化程序(在不同的项目中有很多)。
标签: c++ visual-studio-2012 linker