gcc -O0 -O1 -O2 -O3 -Os 编译优化等级

GCC提供多种优化等级,从-O0到-O3,优化程度逐渐增强。-O0适合调试,保留详细信息;-O1、-O2、O3则通过不同级别的代码优化提高执行效率,-O3可能改变执行顺序。例如,inta=100;在-O3下仅赋值寄存器,-O0则会写入栈中。调试时建议使用-O0。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

优化等级

gcc 提供了大量优化等级,用来对编译时间目标文件大小执行效率三个维度进行不同的取舍和平衡

  • -O0,最少的优化。(这是默认的编译选项)(可以最大程度上配合产生代码调试信息,可以在任何代码行打断点,特别是死代码处)
  • -O-O1,有限优化。(编译时占用稍微多的时间和相当大的内存,减少代码生成尺寸、缩短执行时间)(去除无用的 inline 和无用的 static 函数、死代码消除等,在影响到调试信息的地方均不进行优化,在适当的代码体积和充分的调试之间平衡,代码编写阶段最常用的优化等级)
  • -O2,高度优化。(在 -O1 的基础上,尝试更多的寄存器级的优化以及指令级的优化)(调试信息不友好,有可能会修改代码和函数调用执行流程,自动对函数进行内联)
  • -O3,最大程度优化。(在 -O2 的基础上,针对循环进行更多的优化,更激进的函数内陆等)
  • -Os,相当于 -O2.5。使用了所有 -O2 的优化选项,但又不缩减代码尺寸的方法。

实战演练

使用 STM32CubeMX 新建一个简单 demo,并用 Keil5 打开,使用 STM32CubeMX 创建的工程,gcc 编译优化等级默认为 -O3。
在 main() 函数里有一句 int a = 100;,打开仿真,发现这句被编译成的汇编语句为

MOVS r0,#0x64

即,将 r0 寄存器赋值为 100,就没有然后了。


我们手动将优化等级改为 -O0,重新看 int a = 100; 对应的汇编语句,发现是两句

MOVS r0,#0x64
STR  r0,[sp,#0x00]

即,将 r0 寄存器赋值为 100,然后将 r0 寄存器中的值设置到 sp + 0x00 对应的内存位置,sp 即为栈顶。因为 a 是 main() 函数中第一个定义的变量,所以正好处于栈顶。

两者对比,-O3 优化的结果是:int a = 100; 语句并没有将 a 对应的内存真正的赋值为 100,而是等到后面使用时再进行赋值(已证实),这样做的好处是,如果后续没有对 a 的访问,真正的赋值工作可以不用做了。
-O0 由于没有优化,所以 int a = 100; 语句就乖乖地将 a 对应的内存真正的赋值 100 了。

调试的时候,要使用 -O0,不然你大概率会发现程序并不是按照你预期的顺序执行的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Li-Yongjun

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值