【发布时间】:2013-06-28 05:49:22
【问题描述】:
我正在编写对性能敏感的代码,这确实需要我强制内联某些函数调用。
对于通过头文件在翻译单元之间共享的内联函数,通常必须将函数定义放在头文件中。我不想那样做。其中一些函数对不应在标头中公开的复杂数据结构进行操作。
我已经解决了这个问题,只需将所有 .h 和 .c 文件分别添加到一个 .c 文件中,这样就只有一个翻译单元。 (这会减慢重新编译的速度,但还不够重要。)
这将是“解决问题”,但是当一个 C 文件中的函数调用另一个 C 文件中应该是私有的函数时,它消除了出现错误,并且我想在这种情况下得到一个错误。所以,我有一个单独的 Makefile 条目,它执行“正常”构建,只是为了检查这种情况。
为了强制声明 inline 的函数在“正常”构建中很好地发挥作用,我实际上定义了一个宏 may_inline,它用于 inline 属性通常的位置。对于普通构建,它被定义为空,对于优化构建,它被定义为“内联”。
这似乎是一个可以接受的解决方案。我能看到的唯一缺点是我不能在具有相同原型的不同 .c 文件中拥有私有函数,但到目前为止,这对我来说并不是什么大问题。
另一个潜在的解决方案是使用GCC's Link-Time Optimization,它应该允许跨翻译单元内联。不过,这是一个新功能,我不相信它总是能按照我想要的方式内联。此外,我只能让它处理琐碎的问题,而不是我的实际代码。
这是一个可以接受的 hack,还是我做了一些非常愚蠢的事情?我以前从未见过这样做的事实让我有点紧张。
【问题讨论】:
-
GCC
-flto已经足够成熟(特别是在 GCC 4.8 中)可以用于生产。你应该信任它(在 GCC 4.8 中) -
@BasileStarynkevitch 谢谢。那么,这是我的首选解决方案。对其他人:我仍然非常对我的问题的任何答案感兴趣,因为正如我所提到的,我可以让 -flto 解决玩具问题,但不是我的实际代码库。我不确定我是否能够找出问题所在。我最终可能会为此打开一个单独的问题。
-
要记住的一件事是,如果您的各种
.c文件在文件范围内使用static变量,那么如果它们具有相同的变量,您最终会得到不希望的和未诊断的共享名称和类型。 -
我仍在研究它,但似乎我无法将 -flto 与 -std=c99 一起使用。删除 -std=c99 (这需要更新我所有的 for 循环)允许程序使用 -flto;但是,我的一些代码变慢了(或者我的分析工具坏了),如果我理解正确,这可能是 -flto 的“正确”行为。希望对此有一个积极的解决方案,但很可能在我的情况下 -flto 不是一个好的选择。
-
你说的不应该暴露在header中是什么意思? ...暴露给谁?当只有一个翻译单元时,它们在 .C 文件中的公开方式与在 .H 文件中的公开方式一样。