gcc优化导致app失败

时间:2010-10-04 11:04:16

标签: c++ gcc compiler-optimization fast-math

在启用优化的情况下,使用GCC for ARM时出现了一个非常奇怪的问题。 在没有优化的情况下编译我的C ++应用程序会生成一个可执行文件 在运行时输出预期的结果。我一打开它 优化 - 即-O1 - 我的应用程序无法产生预期的结果。 我试了几天才发现问题,但我很无能为力。 我从我的代码中删除了任何未初始化的变量,我更正了其中的位置 严格的别名可能会导致问题,但我仍然没有得到正确的结果。

我正在使用GCC 4.2.0 for ARM(处理器是ARM​​926ej-s)并运行应用程序 在Montavista Linux发行版上。

以下是我正在使用的标志:

-O1 -fno-unroll-loops fno-merge-constants -fno-omit-frame-pointer -fno-toplevel-reorder \
-fno-defer-pop -fno-function-cse -Wuninitialized -Wstrict-aliasing=3 -Wstrict-overflow=3 \
-fsigned-char -march=armv5te -mtune=arm926ej-s -ffast-math

一旦我删除-O1标志并重新编译/重新链接应用程序,我就会得到正确的输出结果。正如你从旗帜中看到的那样,我试图禁用任何优化,我认为这可能会导致问题,但仍然没有运气。

有没有人对如何进一步解决这个问题有任何指示?

由于

4 个答案:

答案 0 :(得分:8)

一般来说,如果你说“优化会破坏我的程序”,那么 programm 的99.9%就会被破坏。仅启用优化揭示代码中的错误。

您还应该轻松选择优化选项。只有在非常特殊的情况下,您才需要除标准选项-O0,-O2,-O3和-Os之外的任何其他选项。如果您觉得需要更多特定设置,请注意优化的咒语:

衡量,优化,衡量。

从不通过“直觉”来这里。证明某个非标准优化选项确实对您的应用程序有显着的好处,并理解为什么(即,准确理解该选项的作用以及它对您的代码的影响)。

这不是蒙住眼睛的好地方。

看看你如何使用最具防守性的选项(-O1),然后禁用六个优化,然后添加-ffast-math,让我假设你现在正在做那个

嗯,也许是独眼。

但最重要的是:如果启用优化会破坏您的代码,那么很可能是代码的错误。

编辑:我刚刚在GCC手册中找到了这个:

  

-ffast-math:任何-O选项都不应该启用此选项    因为它可能导致依赖的程序的输出不正确   数学的IEEE或ISO规则/规范的精确实现   功能。

基本上,这确实说明您的-O1 -ffast-math确实可以破解正确的代码。但是,即使带走-ffast-math移除当前问题,您至少应该有一个想法为什么。否则,您可能只是在以后(例如,当您的产品在客户所在地点断开时)将问题现在与问题交换时出现问题。问题真的是-ffast-math,还是-ffast-math 未覆盖的数学代码被破坏了?

答案 1 :(得分:2)

如果可能,应该避免{p> -ffast-math。现在只需使用-O1并删除所有其他优化开关。如果您仍然遇到问题,那么就该开始调试了。

答案 2 :(得分:1)

如果没有看到你的代码,就很难比“你可能有一个bug”更具体。

有两种情况,启用优化会更改程序的语义:

  • 编译器中存在错误,或
  • 您的代码中存在错误。

后者可能是最有可能的。具体来说,您可能依赖于程序中某处的未定义行为。当你使用这个计算机上的这个编译器使用这些编译器标志进行编译时,你依赖的东西恰好是正确的,但是它不是'由语言保证。因此,当您启用优化时,GCC没有义务保留该行为。

告诉我们你的代码。或者在调试器中逐步执行它,直到出现问题为止。

我不能再具体了。它可能是一个悬空指针,未初始化的变量,打破别名规则,甚至只是做一些产生未定义结果的事情之一(如i = i++

答案 3 :(得分:1)

尝试制作最小的测试用例。重写程序,删除不影响错误的内容。您可能会在此过程中自己发现错误,但如果不这样做,您应该拥有可以发布的单屏示例程序。

顺便提一下, if ,正如其他人推测的那样,-ffast-math导致你的麻烦(即只用-O1进行编译工作正常),那么很可能你有在那里你应该重写一些数学。这有点过分简化,但-ffast-math允许编译器基本上重新排列计算,因为你可以抽象数学数字 - 即使在真实硬件上这样做可能会导致稍微不同的结果,因为浮点数不准确。依赖于那种浮点细节可能是无意的。

如果你想了解这个bug,最小的测试用例在任何情况下都是至关重要的。