编译器的“-O0”选项和“-Og”选项有什么区别?
What's the difference between a compiler's `-O0` option and `-Og` option?
当我想调试 C 或 C++ 程序时,我被教导使用 -O0
关闭优化,并使用 -ggdb
将符号插入优化的可执行文件中使用我使用的 GNU gdb
调试器(或者,您可以将 -glldb
用于 LLVM/clang 的 lldb
调试器,或者仅使用 -g
作为通用调试符号,但这显然不如 -ggdb
好......)。然而,我最近偶然发现有人说要使用 -Og
(而不是 -O0
),这让我措手不及。果然,它在 man gcc
!:
-Og
Optimize debugging experience. -Og
enables optimizations that do not interfere with debugging. It should be the optimization level of choice for the standard edit-compile-debug cycle,
offering a reasonable level of optimization while maintaining fast compilation and a good debugging experience.
那么,有什么区别呢?这是来自 man gcc
的 -O0
描述:
-O0
Reduce compilation time and make debugging produce the expected results. This is the default.
man gcc
清楚地说 -Og
“应该是标准编辑-编译-调试循环的优化级别”。
这听起来像是 -O0
是真正的“无优化”,而 -Og
是“进行了一些优化,但只是那些不干扰调试的”。这个对吗?那么,我应该使用哪个,为什么?
相关:
- 相关,但不是重复! (仔细阅读,它根本不是重复的):What is the difference between -O0 ,-O1 and -g
- 我对调试的回答
--copt=
与 Bazel 一起使用的设置:gdb: No symbol "i" in current context
@kaylum 刚刚在我的问题下的评论中提供了一些很好的见解!我最关心的关键部分是:
[-Og
] is a better choice than -O0 for producing debuggable code because some compiler passes that collect debug information are disabled at -O0.
https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#Optimize-Options
所以,从现在开始,除了 -ggdb
.
,我还使用 -Og
(不是 -O0
)
UDPATE 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
= <optimized out>
然而,使用 -O0
,一切正常!
(gdb) print angle
= -1.34869879e+20
(gdb) print &angle
= (float *) 0x7ffffffefbbc
(gdb) x angle
0x8000000000000000: Cannot access memory at address 0x8000000000000000
(gdb) x &angle
0x7ffffffefbbc: 0xe0e9f642
所以,回到使用 -O0
而不是 -Og
是!
相关:
- [他们也推荐
-O0
,我同意]What does <value optimized out> mean in gdb?
当我想调试 C 或 C++ 程序时,我被教导使用 -O0
关闭优化,并使用 -ggdb
将符号插入优化的可执行文件中使用我使用的 GNU gdb
调试器(或者,您可以将 -glldb
用于 LLVM/clang 的 lldb
调试器,或者仅使用 -g
作为通用调试符号,但这显然不如 -ggdb
好......)。然而,我最近偶然发现有人说要使用 -Og
(而不是 -O0
),这让我措手不及。果然,它在 man gcc
!:
-Og
Optimize debugging experience.-Og
enables optimizations that do not interfere with debugging. It should be the optimization level of choice for the standard edit-compile-debug cycle, offering a reasonable level of optimization while maintaining fast compilation and a good debugging experience.
那么,有什么区别呢?这是来自 man gcc
的 -O0
描述:
-O0
Reduce compilation time and make debugging produce the expected results. This is the default.
man gcc
清楚地说 -Og
“应该是标准编辑-编译-调试循环的优化级别”。
这听起来像是 -O0
是真正的“无优化”,而 -Og
是“进行了一些优化,但只是那些不干扰调试的”。这个对吗?那么,我应该使用哪个,为什么?
相关:
- 相关,但不是重复! (仔细阅读,它根本不是重复的):What is the difference between -O0 ,-O1 and -g
- 我对调试的回答
--copt=
与 Bazel 一起使用的设置:gdb: No symbol "i" in current context
@kaylum 刚刚在我的问题下的评论中提供了一些很好的见解!我最关心的关键部分是:
[
-Og
] is a better choice than -O0 for producing debuggable code because some compiler passes that collect debug information are disabled at -O0.
https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#Optimize-Options
所以,从现在开始,除了 -ggdb
.
-Og
(不是 -O0
)
UDPATE 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
= <optimized out>
然而,使用 -O0
,一切正常!
(gdb) print angle
= -1.34869879e+20
(gdb) print &angle
= (float *) 0x7ffffffefbbc
(gdb) x angle
0x8000000000000000: Cannot access memory at address 0x8000000000000000
(gdb) x &angle
0x7ffffffefbbc: 0xe0e9f642
所以,回到使用 -O0
而不是 -Og
是!
相关:
- [他们也推荐
-O0
,我同意]What does <value optimized out> mean in gdb?