我在VC ++中玩function-level linking。我启用了/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.obj
。 B.obj
引用了variable1
,因此它包含A.obj
。然后开始未引用的东西消除阶段。它会删除A.obj
和B.obj
中的所有函数,但不会删除变量。 variable
和variable2
都与其静态初始化程序和取消初始化程序一起保留。这会使图像大小膨胀,并导致运行初始化程序和取消初始化的延迟。
上面的代码过于简单,在实际代码中我真的无法轻易地将variable2
移动到C.cpp
。我可以把它放到一个单独的.cpp文件中,但看起来真的很蠢。有没有更好的选择来解决Visual C ++ 9的问题?
答案 0 :(得分:2)
MSDN(请参阅Arguments
部分,REF | NOREF
参数,第4段)指定You have to explicitly mark data as a COMDAT; use __declspec(selectany).
,以便链接器在使用{{1}时删除所述未使用的数据}。
你有没有尝试__declspec(selectany)?