c++ - 如何防止 VC++ 9 链接器链接不必要的全局变量?

标签 c++ visual-c++ linker

我正在玩 function-level linking在 VC++ 中。我启用了 /OPT:REF and /OPT:ICF链接器很乐意删除所有未使用的函数。变量不是这样。

以下代码仅用于演示问题,我完全理解实际以这种方式构建代码是次优的。

//A.cpp
SomeType variable1;

//B.cpp
extern SomeType variable1;
SomeType variable2;
class ClassInB {
 //actually uses variable1
};

//C.cpp
extern SomeType variable2;
class ClassInC {
 //actually uses variable2;
};

所有这些文件都被编译成一个静态库。消费者项目仅使用 ClassInC 并链接到静态库。现在是 VC++ 9 链接器。

首先,链接器看到 C.obj 引用 variable2 并包含 B.objB.obj 引用 variable1,因此它包含 A.obj。然后未引用的东西消除阶段开始。它删除 A.objB.obj 中的所有函数,但不删除变量。 variablevariable2 都与它们的静态初始化器和反初始化器一起保存。这会增大图像大小并引入运行初始化程序和取消初始化程序的延迟。

上面的代码过于简单,在实际代码中我真的不能轻易地将variable2移动到C.cpp中。我可以将它放入一个单独的 .cpp 文件中,但这看起来真的很愚蠢。是否有更好的选择来解决 Visual C++ 9 的问题?

最佳答案

MSDN (参见 Arguments 部分,REF | NOREF arguments,第 4 段)指定 您必须明确地将数据标记为 COMDAT;使用 __declspec(selectany). 链接器在使用 /OPT:REF 时删除所述未使用的数据。

您是否尝试过并有机会使用__declspec(selectany)? ?

关于c++ - 如何防止 VC++ 9 链接器链接不必要的全局变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2369515/

相关文章:

c++ - 如何在 Observer 中处理具有不同状态值类型的 Observable

c++ - Visual Studio 2012 __cplusplus 和 C++ 11

C++ MySQL 连接器无法断开 sql::Connection close() 调用上的 TCP 连接

c - 这个错误在c中意味着什么?

c++ - 几个CUDA文件链接错误LNK2005

c++ - 无法声明没有名称的类模板

c++ - C++ 中的位缓冲区

c - 显式 glibc 链接后为 "Segmentation fault (core dumped)"。

c++ - 结构数组的动态内存分配

c++ - 混合 VS2012 平台工具集