是否可以为特定的代码段禁用gcc/g ++优化?

Mak*_*gan 2 c optimization gcc

我正在编译一些没有优化的代码但是在启用优化的情况下中断.我怀疑代码的某些关键部分被优化了,导致逻辑崩溃.

我想做的事情如下:

code...

#disable opt

more code...

#enable opt
Run Code Online (Sandbox Code Playgroud)

如果我可以设置该部分的优化级别(如O0,O1 ......)会更好

对于那些暗示它是代码的人:

要删除的代码部分是(通过反汇编目标文件来检查):

void wait(uint32_t time)
{
  while (time > 0) {
    time--;
  }
}
Run Code Online (Sandbox Code Playgroud)

我严重怀疑该代码有问题

Sco*_*ttK 5

如果优化导致您的程序崩溃,那么您有一个错误,应该修复它.通过不优化这部分代码来隐藏问题是一种糟糕的做法,会使代码变得脆弱,而且就像为下一个支持代码的开发人员留下地雷一样.更糟糕的是,忽略它,你将无法学习如何调试这些问题.

一些可能的根本原因:

正在优化的硬件访问:使用易失性 关键代码不太可能被优化,尽管如果您正在触摸硬件寄存器,那么您应该添加volatile属性以强制编译器访问这些寄存器而不管优化设置如何.

竞争条件:使用互斥锁或信号量来控制对共享数据的访问权限您更有可能具有特定于时间的竞争条件,并且优化会导致此时间条件显示出来.这是一件好事,因为这意味着你可以解决它.您是否有多个线程或进程访问相同的硬件或共享数据?您可能需要添加互斥锁或信号量来控制访问以避免计时问题.

Heisenbug:这是代码行为根据是否添加调试语句或代码是否优化而发生变化的时间.有一个很好的例子在这里,其中优化的代码也以高精度寄存器浮点比较,但是当加入的printf的,则该值存储为双打和精度较低比较.这导致代码单向失败,而另一方失败.也许这会给你一些想法.

时序循环得到优化:创建一个等待函数,通过创建一个递增局部变量以增加延迟的定时循环,这不是一个好的编程风格.可以基于编译器和优化设置完全优化这样的循环.此外,如果您移动到其他处理器,延迟量将会改变.延迟功能应该基于CPU滴答或实时工作,这不会得到优化.延迟功能使用CPU时钟或实时时钟,或调用标准功能(如nanosleep())或使用超时选择.请注意,如果您使用的是CPU滴答,请务必对该功能进行评论,并强调该实现需要针对特定​​目标.

结论:正如其他人所建议的那样,将可疑代码放在一个单独的文件中并编译该单个源文件而不进行优化.测试它以确保它正常工作,然后将一半代码迁移回原始代码,并重新测试一半代码优化而不是一半代码,以确定您的错误位置.一旦你知道哪一半有Heisenbug,使用分而治之来重复这个过程,直到你找到优化后失败的最小代码部分.

如果你能在那时找到bug,那太好了.否则在这里发布该片段,以便我们可以帮助调试它.提供编译器optmization标志,用于在优化时使其失败.

  • @Makogan:由于代码不使用递增变量,因此编译器完全允许省略代码.你必须伪装你正在做的更好,以避免编译器优化掉一个根本没有任何可检测的副作用的函数.例如,您可能需要将递增的变量分配给全局变量 - 否则会阻止编译器删除代码. (2认同)