如果你想构建一个可调试的东西(特别是g ++,但也许与gcc分享一个答案),那么最好的-O级别是什么?换句话说,在构建“调试”目标而不是“释放”目标时。
在比较-O0和-O1(here)时,gcc在线文档有点粗略。我的解释是-O1只能实现一个甚至可能影响可调试性的优化,即-fomit-frame-pointer。但引用该文档时,它只在-O1中启用,“这样做不会干扰调试。”我正确地解释了吗?
这个网站上的另一篇文章(here)特别谈到了-O2,答案基本上是“它可以运行,但是你会得到无序执行”。其中,IMO可以从烦人到毁灭,取决于事物的跳跃程度。
答案 0 :(得分:49)
GCC 4.8引入了一个新的优化级别:-Og
,用于两全其美。
-OG
优化调试体验。 -Og启用不会干扰的优化 调试。它应该是标准的首选优化级别 编辑 - 编译 - 调试周期,在维护时提供合理的优化级别 快速编译和良好的调试经验。
通过这种方式,可以进行一些优化,从而获得更好的性能,更好的可能 - 未初始化的变量检测,并且您还可以在GDB中逐步执行程序而无需在函数中来回跳转。
答案 1 :(得分:26)
那么......什么标志适合调试构建?
无论你在调试什么都很舒服。
使用-g -O0
构建时,调试最简单,但代码运行速度非常慢。
使用-g -O1
构建时,您将开始观察优化有时。你将尝试进入一个函数,并发现它被内联等等。
使用-g -O2
,您会发现优化很多。打印变量[1]时会得到optimized out
,你会在代码中出现意外跳跃等。
使用-g -O3
,您会看到相同的症状,但更频繁。
GCC实际上没有超过-O3
的等级,所以这就是该行的结尾。
了解GCC使用-O3
执行转换的人在调试代码时几乎没有问题(您可以随时查看程序集,找出您希望实际所在的变量所在的位置,以及从那里开始)。但对于凡人而言,通常很难调试-O2
代码。
[1]目前GDB和GCC目前正在努力减少optimized out
个实例的数量,但还没有完成。
答案 2 :(得分:-3)
调试模式(-g
)和优化级别(-O*
系列)是独立的问题。 -g
标志基本上指示gcc在编译时包含调试符号(以及一些与代码中的行号对应的提示)。它可以应用于任何优化级别。
因此,简单的答案是“构建生产程序时最佳的g ++优化级别”,这是一个更长的讨论