【问题标题】:Optimization flags cause incorrect computation优化标志导致不正确的计算
【发布时间】:2012-12-08 16:08:30
【问题描述】:

我遇到了一个奇怪的仅优化错误,所以我试图确定是哪个标志导致它。 -O1 会出现错误(计算不正确),但-O0 不会。因此,我认为我可以使用所有-f flags-O1 includes to narrow down the culprit。但是,当我尝试这样做时(使用此列表http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html),它又可以正常工作了!

任何人都可以解释这一点,或者就寻找什么提供其他建议吗?我通过valgrind运行了代码,没有报错。

编辑

我发现-O0 的计算正确,-O1 的计算不正确,但-O1 -ffloat-store 的计算再次正确。如果没有-ffloat-store,有什么想法会导致它无法工作吗?

EDIT2

如果我使用正常的发布标志进行编译,则会出现计算错误。但是,如果我添加任何一个:

-ffloat-store

-mpc64

到标志列表,错误消失。

任何人都可以提出一种方法来追踪该标志产生影响的那一行,以便我可以更改它,而不是要求使用代码的每个人都使用额外的标志进行编译?

【问题讨论】:

  • scratchin beard 好吧,除了您列表中提到的“计算过的 goto”之外,我不会放弃这种行为。但是......我曾经遇到过一个问题,因为宏调用结束时缺少分号(神奇地没有发生在 o0 和调试上)
  • 应该还有-o2-o3
  • 你能给我们一个最小的完整例子吗?
  • -ON 标志还可以启用没有任何关联标志的优化。
  • @NikosC。有没有办法单独启用它们?找出导致问题的优化似乎是一个很好的策略,所以我可以明确地寻找它? Beta - 抱歉,这是在一个巨大的库中,我无法在任何小情况下复制它。

标签: c++ gcc g++


【解决方案1】:

从我的 GCC/C++ 时代开始,我记得的像这样的优化错误是,在未指定返回值的方法上使用 -O0 将返回该方法中该类型的最后一个值(可能是您想要的返回对吗?)而对其进行了优化,则返回了该类型的默认值,而不是该方法中该类型的最后一个值(这可能仅适用于值类型,我不记得了)。这意味着您将在调试标志打开的情况下开发很长时间,并且一切看起来都很好,然后在您优化时它将停止工作。

对我来说,不指定返回值是一个编译错误,但那是当时的 C++。

解决方案是打开最强的警告集,然后将所有警告视为错误:这将突出显示此类内容。 (如果您还没有这样做,那么您将承受巨大的痛苦!)

如果您已经有所有错误/警告,那么唯一的另一个选择是优化带有副作用的方法调用。这将更难追踪。

【讨论】:

  • 这类问题到处都是未定义的行为。提高警告级别是抓住这些的最佳机会。
  • @rubenvb - 我正在使用 -Wall ,我应该使用什么?
  • @DavidDoria 我使用-std=c++11 -pedantic -Wextra -Wconversion -Wuninitialized -Winit-self -Wmissing-include-dirs -Wstrict-aliasing。不幸的是,它并不能捕获所有内容,因为根据定义,某些 UB 只能在运行时检测到。
  • @rubenvb 我使用这些标志进行编译,但没有任何反应。这让我疯狂了大约一年,现在我终于有时间研究它了,但不知道该怎么办哈哈。
  • 你也试过 Clang 吗?该手册没有列出全局优化选项之间的所有差异。您应该能够通过在命令中添加“-v”来查看后端调用,这可能会揭示更多的胆量。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-02
  • 2017-03-19
  • 2018-04-20
  • 1970-01-01
  • 1970-01-01
  • 2020-12-26
  • 1970-01-01
相关资源
最近更新 更多