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

Pra*_*tic 9 c c++ gcc g++ inlining

海湾合作委员会的文件包含以下内容:

当函数既是内联函数又是静态函数时,如果对函数的所有调用都集成到调用者中,并且从不使用函数的地址,则永远不会引用函数自己的汇编代码.在这种情况下,除非指定选项-fkeep-inline-functions,否则GCC实际上不会为函数输出汇编代码.由于各种原因,某些调用无法集成(特别是,无法集成函数定义之前的调用,也无法在定义中进行递归调用).

这总是听起来很荒谬 - 为什么现代编译器会那么愚蠢?经过快速测试后,看起来确实不真实.

测试代码:

static inline int foo();

int bar() {
    return foo();
}

int foo() {
    return 42;
}
Run Code Online (Sandbox Code Playgroud)

在Linux上使用gcc-4.9.2的结果包含bar()但没有的代码foo().你可以看到foo()已经集成:

bar:
.LFB0:
    .cfi_startproc
    movl    $42, %eax
    ret
    .cfi_endproc
Run Code Online (Sandbox Code Playgroud)

如果我编译为C++,结果是相同的,除了名称修改.

相反,文档,尽管foo()在呼叫之后被定义bar(),foo()已经完全融入bar().

我是否误解了文档或是不正确的?对于一些更复杂的案例,这可能是正确的吗?

我不知道"集成"和"内联"之间是否存在技术上的区别,但我怀疑"集成"用于区分关键字inline,它只是指函数内联(因此标题).

这个问题被标记为C和C++,因为gcc文档的这一部分属于"C语言系列",我希望这两种语言的答案是相同的.

APr*_*mer 7

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

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