如何在C ++中清楚地生成内联结果

时间:2014-08-12 20:44:30

标签: c++ gcc optimization assembly inlining

我一直在读斯科特迈耶斯' 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选项或使用不同的(非平凡的?)代码片段)来产生这样的输出?

1 个答案:

答案 0 :(得分:3)

编译器完全可以免费内联函数,即使你没有要求它 - 无论是否使用inline关键字,或者你是否使用-finline-functions(尽管可能不是你使用-fnoinline-functions - 这与你要求的相反,虽然C ++标准没有这么说,但如果它没有像它所说的那样做,那么这个标志变得毫无意义。

接下来,编译器也不总是确定你的函数不会在“其他地方”使用,所以它会生成大多数内联函数的外联副本,除非它完全清楚它“不能”可能是从其他地方调用[例如,声明类不能到达其他地方]。

如果你不使用函数的结果,并且函数没有副作用(例如写入全局变量,执行I / O或调用函数编译器“不知道是什么它确实“),然后编译器将该代码消除为”死“ - 因为你真的不想要不必要的代码,对吗?在return函数中的max(i)前面添加foo应该有所帮助。