【发布时间】:2012-11-07 10:04:19
【问题描述】:
我的 c/obj-c 代码(一个用 clang 构建的 iOS 应用程序)有一些被#ifdefs 排除的功能。我想确保从这些函数调用而不是从其他函数调用的代码(死代码)在链接时被剥离(消除)。
我试过了:
- 在应消除的函数中添加本地文字 char[];在可执行文件上运行
strings时,该字符串仍然可见。 - 添加一个应该被淘汰的功能;运行字符串时,函数名仍然可见。
在你问之前,我正在为发布而构建,并且所有剥离设置(显然包括死代码剥离)都已启用。
这个问题并不是 xcode/apple/iOS 特定的;我认为答案在任何 POSIX 开发平台上都应该几乎相同。
【问题讨论】:
-
相关函数是否定义为
static?它们必须存在,否则编译器必须保留它们,以防其他目标文件中的其他代码想要调用它们。 -
不,它们不是静态的,但我的观点是在链接时消除。链接器确实知道它们是否被使用。
-
听起来好像你手头有一个项目......通常,链接器只是简单地获取目标文件中的所有内容并修复它。如果你想要全程序优化(并且死代码消除可以被视为一种优化),那么你需要看看GCC中的工作是否有帮助,如果失败,你总是可以自己编写。如果未使用的函数是静态的,编译器会有所帮助。如果它们不能是静态的,那么您会将它们包含在可执行文件中。如果你想消除未使用的,你需要更加小心你的条件代码。
-
@noamtm 直到最近,GNU 工具链才能够在链接时删除部分目标文件。 That feature is now available 但尚未广泛使用。您可能没有使用它。它也不简单:它依赖于让编译器将一堆额外信息写入链接器然后使用的目标文件。
-
基于llvm的iOS工具链支持死码消除;事实上,当我关闭它时,最终的二进制文件 确实 变大了。但它似乎并没有删除我上面写的东西。