GCC 4.8:Og是否意味着-g?
最近更新了GCC4.8的文档,现在引入了一个新的优化开关,GCC 4.8:Og是否意味着-g?,gcc,Gcc,最近更新了GCC4.8的文档,现在引入了一个新的优化开关,-Og。这个 […]解决了快速编译和卓越调试体验的需要,同时提供了合理水平的运行时性能。总体开发经验应优于默认的优化级别-O0 此开关是否意味着-g或者我必须手动将其添加到我的cxflags中?简短回答:不,您仍然必须手动添加-g 长答案: 我一直在努力直接从源头上找到一个难以回答的答案,所以我决定用这里描述的方法自己测试一下: 我用-O3标志构建了一个可执行文件,但没有-g。使用objdump--syms | grep debug并没有
-Og
。这个
[…]解决了快速编译和卓越调试体验的需要,同时提供了合理水平的运行时性能。总体开发经验应优于默认的优化级别-O0
此开关是否意味着
-g
或者我必须手动将其添加到我的cxflags
中?简短回答:不,您仍然必须手动添加-g
长答案:
我一直在努力直接从源头上找到一个难以回答的答案,所以我决定用这里描述的方法自己测试一下:
我用-O3
标志构建了一个可执行文件,但没有-g
。使用objdump--syms | grep debug
并没有产生预期的结果
然后,我构建了一个带有-g
且没有任何优化标志的可执行文件。相同的objdump
命令产生如下六种结果:
0000000000000000 l d.调试信息0000000000000000.调试信息
我最终构建了一个带有-Og
标志而不带-g
的可执行文件。objdump
命令没有产生任何结果。这意味着调试符号在本例中不存在
虽然我无法从GCC本身找到任何明确的文档,但是(正如Marco Scannadinari之前提到的)证实了我的断言,即
-Og
并不意味着-g查看GCC 4.9.2源代码(GCC/opts.c)表明-Og
与-O1
相同,但禁用某些标志可能会导致更糟糕的调试体验:
/*在函数默认选项优化中:*/
案例选择:
/*-Og选择优化级别1*/
选择->x\u优化\u大小=0;
选择->x_优化=1;
opts->x\U optimize\U fast=0;
opts->x\u optimize\u debug=1;
打破
几步之后,使用一组选项和x\u optimize\u debug
标志调用函数maybe\u default\u option
。当使用-Og
时,将不会启用标有OPT\u LEVELS\u 1\u PLUS\u NOT\u DEBUG
、OPT\u LEVELS\u 1\u PLUS\u SPEED\u ONLY
和OPT\u LEVELS\u 2\u PLUS\u SPEED\u ONLY
的选项
所以这就是“应该比-O0更好”这句话的来源-Og
介于-O0
和-O1
之间。这不会影响通过-g
选项启用的调试信息的包含。您可能还会对不同的-g
选项感兴趣:
- 选项
-ggdb
覆盖-g
。也就是说,如果在-g
之后设置-ggdb
,则-g
选项实际上会被忽略
- 选项
-g
等于-g2
,省略-g
与-g0
相同
- 选项
-g3
产生比-g2
更大的调试部分,-ggdb3
对-ggdb2
产生的调试部分也更大
- 更高的优化级别都会增加代码和调试部分。(
-O0
-O1
-Og
-O2
-O3
)
strip--strip debug
产生的对象大小与-g
级别无关。这与预期相符,即只有-O
级别对实际代码有影响,其中-g
确定调试部分
strip——在对象中保留调试
结果,其中大小由-g
级别控制,然后是-O
级别。(因此-g0-O3
小于-g3-O0
)
注:这里我没有考虑编译的时间。它可能会随着更积极的优化级别而增加。我认为调试级别对时间的影响很小(与优化相比),因为这只意味着在传递过程中需要跟踪额外的细节
下面是我用来测试实际行为的命令(也比较-ggdbX
而不是-gX
):
显然不是“注意-Og并不意味着-g,它只是禁用了可能会干扰调试的优化。”-Gentoo Wikit如果能证明这两个语句中的任何一个,也许是从gcc中摘录的代码,那就好了?如果作为答案发布,我将接受并投票表决。
for g in -g0 -g2 -g3;do
for O in -O0 -O1 -O2 -O3 -Og; do
flags="$g $O";
gcc -fPIC -rdynamic -c -Wall -Wextra -Ilib ltunify.c -o obj/gL_"${flags// /_}_.o" $flags || break;
done;
done