我一直在读斯科特迈耶斯' Effective C++,更具体地说,关于内联的第30项。
所以我写了以下内容,试图用gcc 4.6.3
来诱导优化// test.h
class test {
public:
inline int max(int i) { return i > 5 ? 1 : -1; }
int foo(int);
private:
int d;
};
// test.cpp
int test::foo(int i) { return max(i); }
// main.cpp
#include "test.h"
int main(int argc, const char *argv[]) {
test t;
return t.foo(argc);
}
并使用以下方式生成相关组件:
g++ -S -I. test.cpp main.cpp
g++ -finline-functions -S -I. test.cpp main.cpp
就内联方法而言,两个命令都生成相同的程序集;
我可以看到max()
方法正文(也有cmpl
语句和相关的跳转)及其来自foo()
的调用。
我错过了一些非常明显的东西吗?我不能说我梳理了gcc手册页,但找不到任何相关内容。
所以,我只是将优化级别提高到-O3
,默认情况下启用内联优化,根据:
g++ -c -Q -O3 --help=optimizers | grep inline
-finline-functions [enabled]
-finline-functions-called-once [enabled]
-finline-small-functions [enabled]
不幸的是,这个优化(如预期)上面的代码片段几乎不存在。
max()
不再存在(至少作为明确标记的程序集块)并且foo()
已缩减为:
_ZN4test3fooEi:
.LFB7:
.cfi_startproc
rep
ret
.cfi_endproc
目前我无法清楚地理解(并且超出了研究范围)。
理想情况下,我希望看到的是max()
块中foo()
的汇编代码。
有没有办法(通过cmd-line选项或使用不同的(非平凡的?)代码片段)来产生这样的输出?
答案 0 :(得分:3)
编译器完全可以免费内联函数,即使你没有要求它 - 无论是否使用inline
关键字,或者你是否使用-finline-functions
(尽管可能不是你使用-fnoinline-functions
- 这与你要求的相反,虽然C ++标准没有这么说,但如果它没有像它所说的那样做,那么这个标志变得毫无意义。
接下来,编译器也不总是确定你的函数不会在“其他地方”使用,所以它会生成大多数内联函数的外联副本,除非它完全清楚它“不能”可能是从其他地方调用[例如,声明类不能到达其他地方]。
如果你不使用函数的结果,并且函数没有副作用(例如写入全局变量,执行I / O或调用函数编译器“不知道是什么它确实“),然后编译器将该代码消除为”死“ - 因为你真的不想要不必要的代码,对吗?在return
函数中的max(i)
前面添加foo
应该有所帮助。