本文介绍了编译器的 `-O0` 选项和 `-Og` 选项有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我想调试 C 或 C++ 程序时,我被教导使用 -O0 关闭优化,并使用 -ggdb 将符号插入为使用我使用的 GNU gdb 调试器而优化的可执行文件(或者,您可以将 -glldb 用于 LLVM/clang 的 lldb 调试器,或者只是 -g 用于一般调试符号,但这显然不如 -ggdb ...).但是,我最近偶然发现有人说要使用 -Og(而不是 -O0),这让我措手不及.果然,它在 man gcc!:

When I want to do debugging of C or C++ programs, I've been taught to use -O0 to turn optimization OFF, and -ggdb to insert symbols into the executable which are optimized for using the GNU gdb debugger, which I use (or, you can use -glldb for LLVM/clang's lldb debugger, or just -g for general debugging symbols, but that won't be as good as -ggdb apparently...). However, I recently stumbled upon someone saying to use -Og (instead of -O0), and it caught me off-guard. Sure enough though, it's in man gcc!:

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

那么,有什么区别呢?这是 man gcc 中的 -O0 描述:

So, what's the difference? Here's the -O0 description from man gcc:

-O0 减少编译时间,让调试产生预期的结果.这是默认设置.

man gcc 明确表示 -Og应该是标准编辑-编译-调试周期的优化级别选择".

man gcc clearly says -Og "should be the optimization level of choice for the standard edit-compile-debug cycle", though.

这听起来像 -O0 是真正的没有优化",而 -Og 是一些优化,但只有那些不干扰的优化"带调试."这个对吗?那么,我应该使用哪个,为什么?

This makes it sound like -O0 is truly "no optimizations", whereas -Og is "some optimizations on, but only those which don't interfere with debugging." Is this correct? So, which should I use, and why?

  1. 相关,但不重复!(仔细阅读,它根本不是重复的):什么是 -O0 ,-O1 和 -g 的区别
  2. 我对调试 --copt= 设置以用于 Bazel 的回答:gdb:没有符号i"在当前情况下
  1. related, but NOT a duplicate! (read it closely, it's not at all a duplicate): What is the difference between -O0 ,-O1 and -g
  2. my answer on debugging --copt= settings to use with Bazel: gdb: No symbol "i" in current context

推荐答案

@kaylum 刚刚在我的问题下的评论中提供了一些深刻的见解!而我真正最关心的关键部分是:

@kaylum just provided some great insight in their comment under my question! And the key part I really care about the most is this:

[-Og] 是比 -O0 生成可调试代码更好的选择,因为在 -O0 处禁用了一些收集调试信息的编译器通道.

https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#Optimize-Options

所以,从现在开始,除了 -ggdb 之外,我还使用 -Og(不是 -O0).

So, from now on I'm using -Og (NOT -O0) in addition to -ggdb.

UDPATE 2020 年 8 月 13 日:

UDPATE 13 Aug. 2020:

见鬼!没关系.我坚持使用 -O0.

使用 -Og 我得到 <optimized out>Can't take address of "var";这不是左值. 到处都是错误!我不能再打印我的变量或检查它们的记忆了!例如:

With -Og I get <optimized out> and Can't take address of "var" which isn't an lvalue. errors all over the place! I can't print my variables or examine their memory anymore! Ex:

(gdb) print &angle
Can't take address of "angle" which isn't an lvalue.
(gdb) print angle_fixed_p
$6 = <optimized out>

但是,使用 -O0,一切正常!

With -O0, however, everything works fine!

(gdb) print angle
$7 = -1.34869879e+20
(gdb) print &angle
$8 = (float *) 0x7ffffffefbbc
(gdb) x angle
0x8000000000000000:     Cannot access memory at address 0x8000000000000000
(gdb) x &angle
0x7ffffffefbbc: 0xe0e9f642

所以,回到使用 -O0 而不是 -Og 是这样的!

So, back to using -O0 instead of -Og it is!

  1. [他们还推荐 -O0,我同意]
  1. [they also recommend -O0, and I concur] What does <value optimized out> mean in gdb?

这篇关于编译器的 `-O0` 选项和 `-Og` 选项有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!