【发布时间】:2015-06-03 06:38:36
【问题描述】:
很遗憾,我现在没有使用开放代码,因此请考虑这是一个纯理论性质的问题。 我正在使用的 C++ 项目似乎肯定受到以下选项的影响,至少 GCC 4.3 - 4.8 导致了同样的问题,没有注意到 3.x 系列有任何问题(这些选项可能不存在或不工作不同),受影响的是平台 Linux x86 和 Linux ARM。选项本身会自动设置为 O1 或 O2 级别,所以我必须首先找出导致它的选项:
树支配者选择
树-dse
无树
预树
gcse
cse-follow-jumps
这不是我自己的代码,但我必须维护它,所以我怎么可能找到这些选项造成的麻烦的根源。一旦我用“-fno”禁用了上面的优化,代码就可以工作了。 附带说明一下,该项目在 Visual Studio 2008、2010 和 2013 上可以完美运行,没有任何明显的问题或特定的编译器选项。当然,代码不是 100% 跨平台的,所以有些部分是 Windows/Linux 特定的,但即便如此,我也想知道这里发生了什么。 这不是一个重要的问题,因为我可以让代码完美运行,但我仍然对如何追踪这些问题感兴趣。
简而言之:如何识别和找到受影响的代码?
我怀疑这是一个巨大的 GCC 错误,也许我正在使用的代码甚至没有真正的修复,但它对我来说真的很感兴趣。 我认为这些选项中的大多数都是某种消除,我也阅读了这些选项的解释,但我仍然不知道如何从这里开始。
【问题讨论】:
-
您能否隔离出现问题的特定代码位置,例如启用优化时返回意外值的特定函数?然后,您可以比较两种情况下生成的汇编代码(使用
gcc -S),看看编译器生成了哪些不同的指令。在任何情况下,如果您可以创建一个重现问题的SSCCE 会有所帮助,以便我们验证它(即使您的代码已关闭,您也可以将其缩小为一个显示问题的函数) -
如何您的代码不起作用?它开始崩溃了吗?表现很差吗?它会产生意想不到的结果吗?您确实在构建时启用了许多警告,并正确修复了所有警告(例如,不只是丢弃一些东西)?您确定您的代码中没有错误或未定义的行为吗?您是否检查过生成的程序集并将其与未优化的程序集进行比较?也许并不是这些优化具体是这些优化,而是结合其他一些优化导致了问题?
-
博士,博士,当我撞到自己的头时很痛……所以,停止使用使您的代码悲观的优化。在您确定错误并将其报告给 GCC 维护人员并且他们已经修复之前,不要使用不起作用的东西。但我认为 Joachim 有一个重要的观点——你确定代码非常干净,没有任何未定义的行为吗?
-
哦,众所周知,盲目使用
-O3会导致某些代码出现问题,要么生成错误代码,要么生成比-O2慢 的代码。-O2选项通常被认为是一个安全的选项,如果您需要更多优化,那么手动启用所需的特定优化可能会更好。 -
如果程序输出受到优化级别的影响,通常意味着代码依赖于未定义的行为。 MSVC 和 GCC 执行优化的方式不同,MSVC 可能不受潜在 UB 的影响。尝试其他编译器,看看它是否适用于它们。