1

这个问题很简单。假设我编译并链接此代码:

static char const *foo() { static char const *baz = "0123456789ABCDEF"; return baz; }
static char const *(*bar)() = foo;
int main() { return 0; }

Visual C++ 编译器或链接器似乎自动将字符串标记baz为已使用并包含它,即使它显然从未使用过(尽管foo' 的地址已被占用)。

有什么方法可以使编译器或链接器避免包含实际未使用的此类代码?

4

2 回答 2

1

将 foo() 和 bar() 分离到不同的 obj 文件(即不同的 cpp)是一个好的开始 - 但还不够。事实证明,在链接可执行文件时,链接器无论如何都会拉入使用 exe 构建的每个 obj 文件。

解决方案的第二部分是将带有 foo() 和 bar() 的 cpp 提取到静态库中,并使用带有 main() 链接的可执行文件对其进行链接。

AFAICT 没有正式记录确切的 VC 链接设备,但 Raymond在这里进行了调查。此外,如果您选中“使用库依赖项输入” ,这将不起作用

于 2016-11-06T15:04:17.383 回答
0

编译器只有有限的机会(如果有)来删除未使用的符号。每个源文件都被编译成一个 obj 文件,假设所有定义的东西都有可能被其他地方编译的代码引用。链接器有责任从交给它的所有库和目标文件中优化掉未使用的符号。对于链接器来说,仅忽略单个 .obj 输入的一部分可能很困难,但并非不可能。

这对您来说可能就足够了:

  1. 移动main到它自己的源文件,这样main.c引用中没有任何内容foo

  2. 切换到发布版本。确保/OPT:REF设置为您的链接器优化选项。

  3. 做一个“干净的构建”,然后是整个应用程序的完整构建。

于 2016-11-05T22:50:09.640 回答