当我想调试C或C++程序时,我已经学会了使用-O0
关闭优化,并使用-ggdb
将符号插入到可执行文件中,这些符号是为使用GNU gdb
调试器而优化的,我使用(或者,您可以将-glldb
用于LLVM/clang的lldb
调试器,或者仅将-g
用于一般调试符号,但显然没有-ggdb
好......)。我最近偶然发现有人说要使用-Og
(而不是-O0
),这让我措手不及。-Og
最佳化两柴体验。-Og
可启用不会干扰两柴的最佳化。它应该是标准编辑-编译-两柴循环的最佳化选择层级,提供合理的最佳化层级,同时维持快速的编译和良好的两柴体验。
那么,两者有什么区别呢?下面是-O0
与man gcc
的描述:-O0
减少编译时间并使调试产生预期的结果。这是默认值。man gcc
清楚地表明-Og
“应该是标准编辑-编译-调试周期的优化级别选择”。
这听起来像是-O0
真的是“没有优化”,而-Og
是“一些优化,但只是那些不干扰调试的优化”。这是正确的吗?那么,我应该使用哪一个,为什么?
相关:
1.相关,但不是一个重复!(仔细阅读,它不是一个重复):What is the difference between -O0 ,-O1 and -g
1.我对调试--copt=
设置以与Bazel一起使用的回答:gdb:当前上下文中没有符号“i”
1条答案
按热度按时间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.
错误!我无法打印变量或检查它们的内存!例如:然而,有了
-O0
,一切都工作得很好!因此,返回使用
-O0
而不是-Og
!相关:
1.[他们也推荐
-O0
,我同意]〈value optimized out〉在gdb中是什么意思?