编译器是否决定何时内联我的函数(在 C++ 中)?
-
05-07-2019 - |
题
我知道您可以使用 inline 关键字,或者只是将一个方法放入类声明中,例如短构造函数或 getter 方法,但是编译器是否会最终决定何时内联我的方法?
例如:
inline void Foo::vLongBar()
{
//several function calls and lines of code
}
如果编译器认为内联声明会使我的代码效率低下,它会忽略它吗?
作为一个附带问题,如果我在类之外声明了一个 getter 方法,如下所示:
void Foo::bar() { std::cout << "baz"; }
编译器会在幕后内联它吗?
解决方案
在一天结束时,是否内联的功能完全取决于 编译器。通常,函数在流程方面越复杂,编译器内联它的可能性就越小。而一些函数,如递归函数,根本无法内联。
不内联函数的主要原因是它会大大增加代码的整体大小,从而防止iot被保存在处理器的缓存中。这实际上是一种悲观,而不是优化。
至于让程序员决定在脚下或其他地方拍摄自己,你可以自己内联函数 - 编写功能中可能已经作为函数调用站点的代码。
其他提示
是的,是否内联代码的最终决定取决于 C++ 编译器。inline 关键字是建议,而不是要求。
以下是有关 Microsoft C++ 编译器如何处理此决定的一些详细信息
正如许多人已经发布的那样,即使您可以给出强制提示,例如forceinline,最终决定也始终取决于编译器。点击 部分原因是内联不是自动的“更快”。开关。过多的内联可能会使您的代码变得更大,并可能会干扰其他优化。请参阅关于内联函数和性能的C ++ FAQ Lite 一>
正如其他人所说, inline
关键字仅仅是编译器内联代码的建议。由于编译器会定期内联未使用 inline
标记的代码,而不是内联代码,因此该关键字似乎与 register
或(pre-C)一样冗余++ 0x) auto
。
但是, inline
关键字有另外一个影响:它改变了 external 中函数的链接(默认为函数)到内联。内联链接允许每个编译单元包含它自己的目标代码副本,并使链接器从最终的可执行文件中删除冗余副本。如果这提醒您模板,是的,模板也使用内联链接。
是的,编译器有最终决定权。 在VS中,您甚至可以将递归函数内联到指定的深度;)
#pragma inline_depth( [0... 255] )
加上我的5美分......
我发现这篇关于内联的 Guru of Week 文章非常有用。
据我所知,我读到某个地方甚至链接器可能会进行内联,当它链接目标文件并发现链接的代码可以内联时。
的问候,结果 Ovanes
作为一个附带问题,如果我在我的课外宣布了一个getter方法:
void Foo::bar() { std::cout << "baz"; }
编译器是否会将其内联在内?
这取决于。它可以用于同一翻译单元中的所有呼叫者( .cpp
文件及其所有#included定义)。但它仍然需要编译非内联版本,因为在翻译单元之外可能存在该函数的调用者。您可以在高优化级别上看到这一点(如果您的编译器实际上可以这样做)。 (特别是:比较当你在一个.cpp中#include所有.cpp文件与典型布局时发生的情况。在一个翻译单元中的所有定义,这种内联的机会大大增加。)
据我所知,编译器会自动创建一个你在内联声明的函数(或在类声明中写入)非内联的函数,如果它找到一个像for,while等的循环。 这是编译器在内联函数中具有最后发言权的一个示例。
如果你真的,肯定的,绝对的,必须要内联代码,总有宏。 C多年来一直支持这些,因为在编译之前它们只是文本替换,它们确实真实地内联了你所写的内容。
这就是为什么'inline'关键字(甚至,在某些情况下,强制变体)可以承受没有标准的强制方式 - 你总是可以写一个宏。
也就是说,inline关键字通常更好,因为编译器经常知道使内联函数有意义,是因为内联可以与其余的编译器优化进行交互。