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