我正在尝试使用更现代的工具链编译一些遗留代码。我已将我的一个问题跟踪到从gcc 4.6切换到gcc 4.7:
部分功能使用inline
关键字注释。 Gcc因错误消息而失败:
error: inlining failed in call to always_inline 'get_value_global': function body not available
处理此问题的正确方法是什么?功能体怎么没有?编译器是否应该确保它在所有需要它的情况下都可用?
修改
根据要求(在已删除的评论中),导致错误的函数签名示例:
inline struct a_value_fmt const *find_a_value_format(struct base_fmt *base)
{
/* the code */
}
答案 0 :(得分:1)
该错误是源文件中声明的inline
函数的典型错误,而不是头文件中的错误,在这种情况下,编译器无法内联它们(因为要内联的函数的代码必须是可见的正在编译的同一源文件中的编译器)。所以,我要检查的第一件事是所有声明为inline
的函数确实在头文件中定义。
可能是4.7中GCC诊断的变化导致错误浮出水面,并且它在GCC 4.6中保持沉默(但这仅仅是一种推测)。
引用的错误表示该函数是使用__attribute__((always_inline))
声明的。请注意,如果函数声明为always_inline
,则GCC可能无法内联并报告不同(且相当模糊)的错误,但不会使用inline
关键字 - 因此请确保声明为{{1}的任何函数}也被声明为always_inline
。
更多提示:
一般建议,可能不适用:由于这是一个遗留代码库,您可能需要重新评估哪些功能应该内联,哪些功能在关键路径上,哪些不在,基于更新分析结果。有时,inline
被慷慨地使用,即使它不是必需的,也是多余的。在某些情况下,修复可能是在不需要的地方删除inline
关键字。
当在头文件中声明函数时,编译器认为它们是自动内联的(假设它们足够小,编译器认为内联它们将根据其启发式提高性能) - 即使{{ 1}}关键字未使用。 inline
对编译器来说是一种“推荐”,它不必遵守(除非它与inline
属性一起提供)。
现代编译器做出相对聪明的内联决策,所以通常最好让编译器做到这一点,并在应用热点中将函数声明为inline
(并将其实现移动到头文件中),基于分析结果。