根据Intel编译器,Fortran内部写入突然出现错误



我正在处理的Fortran代码有几行类似于

WRITE(filename, '(A16,"_",I4,".dat")') filename, indx

这段代码已经成功编译并运行了数百次,在许多不同的平台和几乎所有主要的编译器上。但是突然之间,最新的(或者,反正是新的)英特尔编译器不喜欢它了。它给出一个警告消息"forrtl: .... Internal file write-to-self; undefined results"。在这行执行之后,"filename"(一个合理的字符数组)变为空白。

我认为问题在于filename既是写入的输入又是内部写入的目的地。解决办法很简单。它可以用filename_tmp之类的东西代替filename作为目的地。但正如我所说的,直到现在,这还从来没有必要。

所以我想知道,文件名作为输入和目的地都违反了Fortran标准,但所有这些编译器这些年来一直对它视而不见,现在英特尔越来越严格?还是英特尔"势利"?还是彻头彻尾的bug ?

执行1对问题的write语句一直是明确禁止的。

我们目前看到(F2018 12.6.4.5.1 p7):

在执行指定内部文件的输出语句期间,该内部文件的任何部分都不能作为求值任何输出列表项的结果而被引用、定义或变为未定义。

filename是一个内部文件,输出列表项filename的求值是对该内部文件的引用。

这不是编译器需要检测的编程冲突,因此您可以将其视为编译器的改进诊断能力/挑剔的情况。没有Fortran程序会因为编译器这种行为的改变而受到损害。

Fortran 66没有内部文件(或字符类型),当然,Fortrans 77、90和95使用不同的单词来达到相同的效果(例如,参见F90 9.4.4):

如果指定了内部文件,则输入/输出列表项不能在该文件中或与该文件关联。

为了避免看起来更有限制,从Fortran 2003开始,输入和输出语句的限制是分开声明的(上面只引用了输出,p8用于输入)。


1注意执行的使用:语句本身作为语句是没有问题的。允许它存在于未到达的源代码中。在编译时检查此语句并不是一件简单的事情。

最新更新