debugging 编译器的'-O 0'选项和'-Og'选项有什么区别?

cgvd09ve  于 2022-11-24  发布在  其他
关注(0)|答案(1)|浏览(222)

当我想调试C或C++程序时,我已经学会了使用-O0关闭优化,并使用-ggdb将符号插入到可执行文件中,这些符号是为使用GNU gdb调试器而优化的,我使用(或者,您可以将-glldb用于LLVM/clang的lldb调试器,或者仅将-g用于一般调试符号,但显然没有-ggdb好......)。我最近偶然发现有人说要使用-Og(而不是-O0),这让我措手不及。
-Og最佳化两柴体验。-Og可启用不会干扰两柴的最佳化。它应该是标准编辑-编译-两柴循环的最佳化选择层级,提供合理的最佳化层级,同时维持快速的编译和良好的两柴体验。
那么,两者有什么区别呢?下面是-O0man gcc的描述:
-O0减少编译时间并使调试产生预期的结果。这是默认值。
man gcc清楚地表明-Og“应该是标准编辑-编译-调试周期的优化级别选择”。
这听起来像是-O0真的是“没有优化”,而-Og是“一些优化,但只是那些不干扰调试的优化”。这是正确的吗?那么,我应该使用哪一个,为什么?

相关:

1.相关,但不是一个重复!(仔细阅读,它不是一个重复):What is the difference between -O0 ,-O1 and -g
1.我对调试--copt=设置以与Bazel一起使用的回答:gdb:当前上下文中没有符号“i”

qjp7pelc

qjp7pelc1#

@kaylum刚刚在我的问题下他们的评论中提供了一些很棒的见解!而我真正关心的关键部分是这样的:
[-Og]比-O 0更适合生成可调试代码,因为在-O 0中会禁用一些收集调试信息的编译器传递。
https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#Optimize-Options
因此,从现在开始,除了-ggdb之外,我还使用-Og(而不是-O0)。
2020年8月13日更新:

管他呢!没关系。我坚持-O0

使用-Og时,到处都是<optimized out>Can't take address of "var" which isn't an lvalue.错误!我无法打印变量或检查它们的内存!例如:

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

然而,有了-O0,一切都工作得很好!

(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

相关:

1.[他们也推荐-O0,我同意]〈value optimized out〉在gdb中是什么意思?

相关问题