gcc documentation包含以下内容:
When a function is both inline and static, if all calls to the function are integrated into the caller, and the function's address is never used, then the function's own assembler code is never referenced. In this case, GCC does not actually output assembler code for the function, unless you specify the option -fkeep-inline-functions. Some calls cannot be integrated for various reasons (in particular, calls that precede the function's definition cannot be integrated, and neither can recursive calls within the definition).
这对我来说总是听起来很荒谬——为什么现代编译器会那么愚蠢?经过快速测试后,它似乎不真实。
测试代码:
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++,结果是相同的,除了名称修改。
与文档相反,尽管在 bar()
中调用之后定义了 foo()
,但 foo()
已完全集成进入 bar()
。
是我误解了文档还是不正确?也许对于一些更复杂的情况是正确的?
我不知道“集成”和“内联”之间是否存在技术区别,但我怀疑“集成”被用来与关键字 inline
区分开来,它只是指函数内联 (因此标题)。
这个问题被标记为 C 和 C++,因为这部分 gcc 文档属于“C 语言家族”,我希望这两种语言的答案相同。
最佳答案
Gcc 曾经一次编译和优化一个函数,一旦它们被解析,就在解析下一个函数之前。 IIRC,他们只是在 4.X 时间框架中引入了 -funit-at-a-time
选项,该选项将优化推迟到阅读整个编译单元之后,然后他们等待一些版本默认情况下启用它。
在调用之后定义内联函数的可能性可能已作为 -funit-at-a-time
工作的一部分引入,并且内联的文档(在定义之前提到调用至少可以追溯到 2.95)当时还没有更新。
关于c++ - 不能内联函数定义之前的调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28365742/