我目前有内联函数调用另一个内联函数(一个简单的4行大getAbs()
函数)。但是,我通过查看汇编代码发现“大”内联函数内联良好,但编译器使用bl
跳转来调用getAbs()
函数。
是否无法在另一个内联函数中内联函数?顺便说一句,这是嵌入式代码,我们没有使用标准库。
编辑:编译器是WindRiver,我已经检查过内联是否有用(4条指令而不是+ -40)。
答案 0 :(得分:8)
inline
关键字是编译器的建议,仅此而已。你可以自由地接受这个建议,完全忽略它,甚至欺骗你,并告诉它它正在做它而不是真的。
强制代码内联的唯一方法是将其内联写入。但是,即便如此,编译器也可能决定更好地了解并决定将其转移到另一个函数。它为您的特定源生成可执行代码有很大的余地,前提是它不会改变它的语义。
现代编译器能够生成比大多数开发人员在装配中手工制作更好的代码。我认为inline
关键字应与register
关键字的路径相同。
如果您已经看到gcc的疯狂优化级别的输出,您就会明白为什么。它产生了我梦寐以求的代码,这让我花了很长时间才能理解。
顺便说一句,请检查this,看看gcc实际上有哪些优化,包括很多包含“内联”或“内联”文本的优化。
答案 1 :(得分:8)
根据您使用的编译器,您可能会鼓励编译器不太勉强内联,例如:使用gcc,您可以使用__attribute__ ((always_inline))
,使用英特尔ICC可以使用icc -inline-level=1 -inline-forceinline
,使用Apple的gcc,您可以使用gcc -obey-inline
。
答案 2 :(得分:1)
@gramm:在很多情况下,内联并不一定对您有利。大多数编译器使用一些非常先进的启发式方法来确定何时内联。在讨论内联时,最简单的想法是,相信您的编译器可以生成最快的代码。
答案 3 :(得分:0)
我最近有一个非常类似的问题,阅读这篇文章给了我一个古怪的想法。为什么不进行简单的预编译(一个简单的注册表应该完成这项工作)代码解析器解析函数调用以实际将源代码放入内联。使用/ 内联 / / end_of_inline /等标记,以便您可以使用常规ide功能(如果您使用或可能使用ide。 在您的构建过程中包含这一点,这样您就具有可读性优势,并且删除了编译器的假设,即您只是与大多数开发人员一样好,并且不了解何时进行内联。
尽管如此,在尝试此操作之前,您应该通过编译器命令行选项。
答案 4 :(得分:-1)
我建议如果你的getAbs()
函数(听起来像绝对值,但你真的应该向我们展示带有问题的代码......)是4行长,那么你需要担心的比代码是否内联。