gcc documentation包含以下内容:
当一个函数既是内联函数又是静态函数时,如果所有函数都调用了 函数被集成到调用者中,函数的地址是 从未使用过,那么函数自己的汇编代码永远不会 引用。在这种情况下,GCC实际上不输出汇编代码 对于该函数,除非您指定该选项 -fkeep内联函数。由于各种原因(特别是在函数定义之前的调用),无法集成某些调用 无法集成,也无法在其中进行递归调用 定义)。
这对我来说总是听起来很荒谬 - 为什么现代编译器会那么愚蠢?经过快速测试后,这似乎是不真实的。
测试代码:
static inline int foo();
int bar() {
return foo();
}
int foo() {
return 42;
}
Linux上gcc-4.9.2的结果包含bar()
的代码,但foo()
没有代码。您可以看到已集成foo()
:
bar:
.LFB0:
.cfi_startproc
movl $42, %eax
ret
.cfi_endproc
如果我编译为C ++,结果是相同的,除了名称修改。
与文档相反,尽管在foo()
中的通话后定义了bar()
,foo()
已完全整合到bar()
。
我是否误解了文档或是不正确的?对于一些更复杂的案例,这可能是正确的吗?
我不知道“整合”和“内联”之间是否有技术上的区别,但我怀疑“整合”是用来区分关键字inline
而它只是指函数内联(因此标题) )。
这个问题被标记为C和C ++,因为gcc文档的这一部分属于“C语言系列”,我希望这两种语言的答案是相同的。
答案 0 :(得分:7)
Gcc用于在解析下一个函数之前,一旦解析它们,就一次编译和优化一个函数。 IIRC,只是在4.X的时间框架内,他们引入了-funit-at-a-time
选项,在读完整个编译单元后推迟了优化,然后等待一些版本默认启用它。
在调用之后定义的内联函数的可能性可能是作为-funit-at-a-time
工作的一部分引入的,并且内联文档(关于定义之前的调用的提及至少可以追溯到2.95)尚未更新然后