编译时测试函数是否被优化

标签 c gcc optimization compiler-optimization

我正在用 C(不是 C++,所以我不能使用模板)为微 Controller 编写一个小型操作系统。它大量使用了一些 gcc 功能,其中最重要的功能之一是删除未使用的代码。操作系统在运行时不加载任何东西;用户的程序和操作系统源代码被编译在一起形成一个二进制文件。

这种设计允许 gcc 只包含程序实际使用的操作系统功能。因此,如果程序从不使用 i2c 或 USB,则二进制文件中不会包含对它们的支持。

问题是当我想在不引入依赖项的情况下包含对这些功能的可选支持时。例如,调试控制台应该提供调试 i2c 的功能(如果它正在使用),但如果程序没有使用它,那么包括调试控制台也不应该引入 i2c。

想到的实现此目的的方法并不理想:

  • 让用户明确启用他们需要的模块(使用 #define),并使用 #if 仅在调试控制台中包含对它们的支持,如果启用。我不喜欢这种方法,因为目前用户不必这样做,我更愿意保持这种方式。

  • 让模块在启动时向调试模块注册函数指针。这并不理想,因为它增加了一些运行时开销,并且意味着调试代码被拆分到多个文件中。

  • 和上面一样,但是使用弱符号而不是指针。但我仍然不确定如何真正实现这一目标。

  • 在调试代码中进行编译时测试,例如:

    if(i2cInit is used) {
        debugShowi2cStatus();
    }
    

最后一种方法看起来很理想,但是有可能吗?

最佳答案

这似乎是一个有趣的问题。这是一个想法,尽管它并不完美:

两次编译。

你可以做的是首先,用像 FINDING_DEPENDENCIES=1 这样的标志编译程序。为此,用 #if 围绕所有依赖项检查(我假设您不太关心在那里添加额外的 ifs。)

然后,当编译完成后(没有任何可选特性),使用nm 或类似的工具来检测程序中函数/特性的使用(例如i2cInit ),并将此信息格式化为 .h 文件。

#ifndef FINDING_DEPENDENCIES
#include "dependency_info.h"
#endif

现在可选的依赖项是已知的。

这似乎仍然不是一个完美的解决方案,但最终,它主要是一个先有鸡还是先有蛋的问题。编译时,编译器不知道哪些符号将被 gc 掉。您基本上需要从链接器阶段获取此信息并将其反馈给编译阶段。

理论上,这可能不会增加很多构建时间,尤其是如果您为生成的 h 使用临时文件,然后仅在它不同时才替换它。不过,您需要使用不同的对象目录。

这也可能有帮助(当然是预剥离): How can I view function names and parameters contained in an ELF file?

关于编译时测试函数是否被优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36962018/

相关文章:

c - 如何修剪字符串数组并将其传递到函数中?

c - 反向单链表

c - gcc链接静态库中未解析符号的顺序是什么

c++ - 如何避免在 linux 上使用系统标准 C/C++ 库?

batch-file - 我的批处理代码有问题。找不到为什么由于括号而引发错误

c++ - 用宏替换重复的 "if" block 是否会降低 C++ 中的代码复杂性?

c - 什么时候进行代码优化?

c - 指针数组并为字符串动态分配内存

c - 有时HPUX和Solaris中的LD_PRELOAD无法生效

c - 链接目标文件和链接包含这些文件的静态库