如何防止 Visual C++ 链接器包含地址被占用的每个函数?
How to prevent the Visual C++ linker from including every function whose address is taken?
问题很简单。假设我编译 & link 这段代码:
static char const *foo() { static char const *baz = "0123456789ABCDEF"; return baz; }
static char const *(*bar)() = foo;
int main() { return 0; }
Visual C++ 编译器或 linker 似乎自动将字符串 baz
标记为已使用,并包含它,即使它显然从未使用过(尽管 foo
的地址被占用)。
有没有什么方法可以让编译器或 linker 避免包含这样的实际未使用的代码?
编译器只有有限的机会(如果有的话)删除未使用的符号。每个源文件都被编译成一个 obj 文件,假设所有定义的东西都有可能被别处编译的代码引用。 链接器 负责从所有传递给它的库和目标文件中优化掉未使用的符号。链接器可能很难(但并非不可能)仅忽略单个 .obj 输入的一部分。
这可能对你来说足够了:
将 main
移动到它自己的源文件中,这样 main.c
中的任何内容都不会引用 foo
.
切换到发布版本。确保将 /OPT:REF
设置为您的链接器优化选项。
执行 "build clean",然后完整构建整个应用程序。
将 foo() 和 bar() 分离到不同的 obj 文件(即,不同的 cpp)是一个好的开始 - 但还不够。事实证明,当 linking 可执行文件 时,linker 无论如何都会拉入使用 exe 构建的每个 obj 文件。
解决方案的第二部分是将带有 foo() 和 bar() 的 cpp 提取到 静态库 中,并让可执行文件带有 main() link反对它。
AFAICT 确切的 VC linking 设备没有正式记录,但 Raymond here. Also, this will not work if you check 'Use Library dependency inputs'
调查过
问题很简单。假设我编译 & link 这段代码:
static char const *foo() { static char const *baz = "0123456789ABCDEF"; return baz; }
static char const *(*bar)() = foo;
int main() { return 0; }
Visual C++ 编译器或 linker 似乎自动将字符串 baz
标记为已使用,并包含它,即使它显然从未使用过(尽管 foo
的地址被占用)。
有没有什么方法可以让编译器或 linker 避免包含这样的实际未使用的代码?
编译器只有有限的机会(如果有的话)删除未使用的符号。每个源文件都被编译成一个 obj 文件,假设所有定义的东西都有可能被别处编译的代码引用。 链接器 负责从所有传递给它的库和目标文件中优化掉未使用的符号。链接器可能很难(但并非不可能)仅忽略单个 .obj 输入的一部分。
这可能对你来说足够了:
将
main
移动到它自己的源文件中,这样main.c
中的任何内容都不会引用foo
.切换到发布版本。确保将
/OPT:REF
设置为您的链接器优化选项。执行 "build clean",然后完整构建整个应用程序。
将 foo() 和 bar() 分离到不同的 obj 文件(即,不同的 cpp)是一个好的开始 - 但还不够。事实证明,当 linking 可执行文件 时,linker 无论如何都会拉入使用 exe 构建的每个 obj 文件。
解决方案的第二部分是将带有 foo() 和 bar() 的 cpp 提取到 静态库 中,并让可执行文件带有 main() link反对它。
AFAICT 确切的 VC linking 设备没有正式记录,但 Raymond here. Also, this will not work if you check 'Use Library dependency inputs'
调查过