对 gcc 的内联选项和GNU GCC的决策过程有一个很好的概述。
这确定了不可能内联的情况:“使用 varargs、使用 alloca、使用可变大小的数据类型、使用计算的 goto、使用非本地 goto 和嵌套函数”
重要的一点是一个非静态函数,即一个带有extern
链接的函数(即每个声明为不带 的函数static
)可以被调用,或者将其地址放在不同的源文件中。
这会强制编译器生成“正常”函数以及任何内联函数体。当然,这会生成一个比仅生成“正常”非内联函数更大的程序。
Gcc 有一个-ffunction-sections
生成目标文件的选项,它使链接器能够消除未使用的函数,但代价是“......汇编器和链接器将创建更大的目标文件和可执行文件,而且速度也会变慢。”
在较新版本的 gcc 上,支持链接时间优化 (LTO)(请参阅“整个程序优化”)。这允许优化阶段查看所有已编译的程序,并进行更积极的内联和优化,并排除未使用的代码。
查看一些较新的gcc-4.6 gcc-4.7过程间优化也很有趣。例如,仅内联内联函数的“热路径”,而不是整个函数。Gcc 也可能生成一个函数的多个实例,因为常量是已知的,并且 gcc 计算出最好有多个实现,每个实现都针对那些已知的常量进行优化。
gcc 中有一些选项可以要求编译器内联所有“足够简单”的函数。
最后它说“根据 ISO C++ 的要求,GCC 认为在类的主体中定义的成员函数被标记为内联,即使它们没有使用 inline 关键字显式声明”。在这种情况下,使用“足够简单”的规则。
总结:编译器可能会做非常聪明的优化,超出普通函数或内联函数的预期。