如何在c++中清晰地生成内联结果

How to clearly produce inlining results in C++

本文关键字:联结 结果 清晰 c++      更新时间:2023-10-16

我又读了一遍Scott Meyers的《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

,我目前无法清楚地理解(并且超出了研究范围)。

理想情况下,我想看到的是foo()块内max()的汇编代码。是否有一种方法(通过命令行选项或使用不同的(非琐碎的?)代码片段)来产生这样的输出?

编译器完全可以自由地使用内联函数,即使你没有要求它——无论你是否使用inline关键字,或者你是否使用-finline-functions(尽管如果你使用-fnoinline-functions可能不会——这将与你所要求的相反,尽管c++标准没有这样说,如果它不做它所说的事情,这个标志就变得相当毫无意义)。

其次,编译器也不总是确定你的函数不会在"其他地方"使用,所以它会产生大多数内联函数的行外副本,除非它完全清楚"不可能从其他地方调用"[例如,类被声明为无法在其他地方访问]。

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