如何在c++中清晰地生成内联结果
How to clearly produce inlining results in C++
我又读了一遍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
应该会有所帮助。
相关文章:
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- valgrind-hellgrind与泄漏检查的结果不同
- 用C++20 fmt限制结果的总大小
- 如何返回一个类的两个对象相加的结果
- 使用QProcess执行命令,并将结果存储在QStringList中
- 如果我std::dynamic_pointer_cast并且底层dynamic_cast的结果为null,那么返回的sh
- 在没有定义返回类型的函数中返回布尔值,并将结果保存在无错误的char编译中-为什么
- 序列化,没有库的整数,得到奇怪的结果
- 使用取消引用的指针的多态性会产生意外的结果.为什么?
- 在更改for循环的第三部分后,未使用for循环结果
- 使用++运算符会导致意外的结果
- 为什么在逗号分隔符上下文中将预增量的结果强制转换为void
- C++Brute Force攻击函数不会返回结果
- 你好。。。id_public变量不应该给出结果为 81 和 86 吗?为什么它为两个派生类占用不同的内存位置?
- 算术运算的结果类似于:C浮点变量中的1/3
- ";结果类型必须是可从输入范围的值类型""构造的;创建std::vector时
- 密码登录程序将永远循环并显示不正确的结果
- 如何让C++'tally up'结果并制定计划?
- 为什么这个程序的结果是3 "born"?和 4 死
- 尝试将字符串/字符转换为整数会产生意外结果