构建调试目标时,最佳g ++优化级别是什么?

Mat*_*att 33 gcc g++

当你想构建一个可调试的东西(特别是g ++,但也许与gcc共享一个答案)时,最好的-O级别是什么?换句话说,在构建"调试"目标而不是"释放"目标时.

当比较-O0和-O1(这里)时,gcc在线文档有点粗略.我的解释是-O1只能实现一个甚至可能影响可调试性的优化,即-fomit-frame-pointer.但引用该文档时,它只在-O1中启用,"这样做不会干扰调试." 我正确地解释了吗?

本网站上的另一篇文章(这里)特别谈到了-O2,答案基本上是"它可以工作,但是你会得到无序执行".其中,IMO可以从烦人到毁灭,取决于事物的跳跃程度.

Ted*_*val 50

GCC 4.8引入了一个新的优化级别:-Og两全其美.

-Og
优化调试体验.-Og启用不会干扰调试的优化.它应该是标准编辑 - 编译 - 调试周期的优化级别,提供合理的优化级别,同时保持快速编译和良好的调试体验.

通过这种方式,可以进行一些优化,从而获得更好的性能,更好的可能 - 未初始化的变量检测,并且您还可以在GDB中逐步执行程序,而无需在函数中来回跳转.

  • “-Og”位于“-O0”和“-O1”之间。另请参阅[我的答案](http://stackoverflow.com/a/27076307/427545),其中讨论了各种“-O”和“-g”级别。 (3认同)
  • 在 g++ 4.9 中对我们的一个库进行的测试中,“-Og”的构建速度比“-O0”慢 20-25%。这是对 GCC 的一个很好的补充,但基于编译时间的损失,我认为它不应该_自动_成为选择的级别。 (2认同)

Emp*_*ian 26

那么...什么标志适合调试构建?

无论你喜欢调试什么.

构建时-g -O0,调试最简单,但代码运行速度非常慢.

在构建时-g -O1,您将开始有时观察优化.您将尝试进入一个函数,并发现它已内联,等等.

有了-g -O2,你会发现很多优化.你会optimized out在打印变量[1]时得到,你会在代码中出现意外跳跃等.

随着-g -O3你会看到相同的症状,但更频繁.

海湾合作委员会实际上没有超出水平-O3,所以这就是该行的结束.

理解GCC执行的转换的人在-O3调试代码时几乎没有问题(你可以随时查看程序集,找出你想要实际存在的变量,并从那里开始).但对于凡人而言,通常很难调试-O2代码.

[1]目前GDB和GCC目前正在努力减少optimized out实例数量,但还没有完成.

  • 我会说gcc的级别超过`-O3`,它是`-Ofast`. (2认同)
  • `-g` 也有不同的级别。例如,“-g”相当于“-g2”,“-g3”可以添加宏扩展。 (2认同)