在开发一个大型fortran软件时,我一次又一次遇到此错误,特别是在使用-O2编译时具有更好的性能。
在某些情况下,错误是真实的,可以纠正,但在其他情况下,我发现没有错误,并假设它是由-O2围绕代码绕而引起的。由于我的老式调试技术是添加靠近发生错误点的写陈述,因此我发现当我这样做时,错误经常消失。
也许是因为-O2优化在此类陈述周围有点仔细地悬而未决。
最近,我在一个循环中遇到了这个错误,这不是很复杂,而且时间不是很关键,并且在循环中添加写入语句阻止了此错误。当我删除写声明时,错误又回来了。为了避免在运行程序时创建很多毫无意义的输出,我发现足以写入内部字符,因此对于用户来说,什么都没有改变。
没有-O2编译代码时没有错误,但是循环使用许多局部变量在模块内部,我不知道如何在没有-O2的情况下分别在模块中编译一个子例程。
。我在Linux和Windows上使用GNU Fortran 7.2.0(此错误仅在Linux上发生,但以前我在Windows上也有类似的问题(。我无法访问任何其他编译器,但我的代码是免费的,并且已与其他编译器一起编译,没有任何问题。
所以我的问题是,是否可以关闭模块内代码的一小部分的O2,或者是否有比添加写入语句以防止-O2在特定子例程中围绕代码进行的替代方案。
我通过网络搜索到达这里,如果它可以帮助任何人,我想在我的情况下分享解决方案。许多评论者提到了非初始化变量的可能性。我的代码没有这样的警告,但是我通过在子例程中分配存储的方式产生了相同的效果,以至于编译器大概没有意识到要在下一行中使用新鲜分配的内存。
我意外地做到了这一点,包括模块中的可分配数组,然后将其作为参数传递给首先进行分配的子例程(使用模块中的名称(,此后立即开始使用数组元素分配值我已经传递的名字是一个论点。当我从-O1搬到-O2时,它停止工作。-fcheck =界限实际上导致代码在没有segfault的情况下运行。
实际上导致代码运行。i通过使用-O2 -G -Traceback在不检查界限的情况下找到了违规行。当我开始使用我作为参数的名称始终指向数组时,问题就消失了。