内联函数只是对编译器的请求,这些编译器在使用该函数的代码中的每个位置插入内联函数的完整主体。
但是编译器如何决定是否应该插入它?它使用哪种算法/机制来决定?
谢谢,
纳温
答案 0 :(得分:4)
一些常见方面:
第三个可能是你问题的核心,但这确实是“编译器特定的启发式” - 你需要检查编译器文档,但通常它们不会提供太多保证。 MSDN有一些(有限的)MSVC信息。
除了琐事(例如简单的getter和非常原始的函数)之外,内联不再是非常有用的了。呼叫指令的成本已经下降,并且分支预测已经大大改善。
内联的绝佳机会是删除编译器知道不会采用的代码路径 - 作为一个极端的例子:
inline int Foo(bool refresh = false)
{
if (refresh)
{
// ...extensive code to update m_foo
}
return m_foo;
}
一个好的编译器会内联Foo(false)
,而不是Foo(true)
。
使用链接时间码生成,Foo
可以驻留在.cpp(没有inline
声明)中,Foo(false)
仍然会内联,所以内联再次只有边际效应
总结:在极少数情况下,您应尝试通过放置(或省略)内联语句来手动控制内联。
答案 1 :(得分:2)
我对内联函数(以及许多其他c ++内容)的所有了解都是here。
另外,如果你专注于每个编译器的启发式方法来决定是否有函数,那么这依赖于实现,你应该看看每个编译器的文档。请记住,启发式也可能会根据优化级别而改变。
答案 2 :(得分:2)
以下是Sun Studio 11编译器的FAQ:
当满足以下任何条件时,编译器会将内联函数生成为普通的可调用函数(不在线):
- 使用+ d。
进行编译- 使用-g。
进行编译- 需要函数的地址(与虚函数一样)。
- 该函数包含编译器无法内联生成的控制结构。
- 功能过于复杂。
根据'clamage45'对此post的响应,“编译器无法生成内联的控制结构”是:
- 该函数包含禁用的构造,如loop,switch或goto
可以找到另一个列表here。正如大多数其他答案所指定的那样,启发式算法将是100%编译器特定的,从我所读到的,我认为确保函数实际内联,你需要避免:
答案 3 :(得分:1)
我很确定大多数编译器根据函数的长度(编译时)以字节为单位决定使用频率与优化类型(速度与大小)的比较。
答案 4 :(得分:1)
我只知道几个标准:
答案 5 :(得分:1)
这取决于编译器。这是GCC手册所说的(第一部分):
-finline-limit=n By default, GCC limits the size of functions that can be inlined. This flag allows the control of this limit for functions that are explicitly marked as inline (i.e., marked with the inline keyword or defined within the class definition in c++). n is the size of functions that can be inlined in number of pseudo instructions (not counting parameter handling). The default value of n is 600. Increasing this value can result in more inlined code at the cost of compilation time and memory consumption. Decreasing usually makes the compilation faster and less code will be inlined (which presumably means slower programs). This option is particularly useful for programs that use inlining heavily such as those based on recursive templates with C++. Inlining is actually controlled by a number of parameters, which may be specified individually by using --param name=value. The -finline-limit=n option sets some of these parameters as follows: @item max-inline-insns-single is set to I/2. @item max-inline-insns-auto is set to I/2. @item min-inline-insns is set to 130 or I/4, whichever is smaller. @item max-inline-insns-rtl is set to I. See below for a documentation of the individual parameters controlling inlining. Note: pseudo instruction represents, in this particular context, an abstract measurement of function's size. In no way, it represents a count of assembly instructions and as such its exact meaning might change from one release to an another.
答案 6 :(得分:-2)
如果你在函数的开头写“内联”,它会插入吗?