无法内联函数定义之前的调用?

时间:2015-02-06 12:22:07

标签: c++ c gcc g++ inlining

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语言系列”,我希望这两种语言的答案是相同的。

1 个答案:

答案 0 :(得分:7)

Gcc用于在解析下一个函数之前,一旦解析它们,就一次编译和优化一个函数。 IIRC,只是在4.X的时间框架内,他们引入了-funit-at-a-time选项,在读完整个编译单元后推迟了优化,然后等待一些版本默认启用它。

在调用之后定义的内联函数的可能性可能是作为-funit-at-a-time工作的一部分引入的,并且内联文档(关于定义之前的调用的提及至少可以追溯到2.95)尚未更新然后