我正在使用最初用 Fortran 77 编写的代码,该代码使用名称列表(在编写时由编译器扩展支持 - 此功能仅在 Fortran 90 中成为标准)来读取输入文件。namelist 输入文件在(多个)纯文本页眉和页脚之间有一组 namelist 变量(请参阅 参考资料example.nml
)。只有在满足先前读取的变量的某些条件时,才会读取某些列表变量组。
当按顺序读取文件中的所有名称列表组时,使用 gfortran、ifort 和 nagfor 编译的可执行文件的行为都相同并给出预期的输出。但是,当要跳过输入文件中的给定名称列表组(可选读取)时,gfortran 和 ifort 可执行文件会根据需要处理此问题,而使用 nagfor 编译的可执行文件会引发运行时错误:
运行时错误:reader.f90,第 27 行:预期的 NAMELIST 组 /GRP3/ 但发现 /GRP2/ 程序因单元 15 上的 I/O 错误而终止(文件 =“example.nml”,格式化,顺序)
作为重现该问题的最小工作示例,请考虑下面给出的 namelist 文件example.nml
和驱动程序reader.f90
,其中NUM2
from namelist groupGRP2
仅应在NUM1
from namelist group GRP1
equals时读取1
:
例子.nml:
this is a header
&GRP1 NUM1=1 /
&GRP2 NUM2=2 /
&GRP3 NUM3=3 /
this is a footer
阅读器.f90:
program reader
implicit none
character(len=40) :: hdr, ftr
integer :: num1, num2, num3, icode
! namelist definition
namelist/grp1/num1
namelist/grp2/num2
namelist/grp3/num3
! open input file
open(unit=15, file='example.nml', form='formatted', status='old', iostat=icode)
! read input data from namelists
read(15, '(a)') hdr
print *, hdr
read(15, grp1)
print *, num1
if (num1 == 1) then
read(15, grp2)
print *, num2
end if
read(15,grp3)
print *, num3
read(15, '(a)') ftr
print *, ftr
! close input file
close(unit=15)
end program reader
在以下情况下,所有可执行文件都会给出预期的输出NUM1=1
:
this is a header
1
2
3
this is a footer
但是,当 eg 时NUM1=0
,使用 gfortran 和 ifort 编译的可执行文件会给出所需的输出:
this is a header
0
3
this is a footer
而使用 nagfor 编译的可执行文件(以严格符合标准而闻名)读取标题和第一个名单组:
this is a header
0
但随后以前面提到的运行时错误终止。
如错误消息所示,example.nml
按顺序访问,如果是这种情况,/GRP2/ 是下一条要读取的记录,而不是程序逻辑要求的 /GRP3/,因此错误消息对我来说很有意义。
所以我的问题是:
- 显示的行为是否可以归因于 nagfor 而不是 gfortran 和 ifort 强制执行的标准(非)一致性?
- 如果是这样,这是否意味着使用 gfortran 和 ifort 观察到的非顺序读取是由于这些编译器支持的扩展(而不是 nagfor)?可以使用编译器标志打开/关闭它吗?
- 我能想到的最简单的解决方法(对大型现有程序的最小更改)是
read(15,*)
在else
分支中if
为reader.f90
. 这似乎适用于所有提到的编译器。这会使代码标准符合(Fortran 90 或更高版本)吗?
这些是用于编译可执行文件的编译器版本和选项:
- GNU Fortran (Ubuntu 9.1.0-2ubuntu2~18.04) 9.1.0:
gfortran -Wall -Wextra -fcheck=all -g -Og -fbacktrace reader.f90
- 英特尔(R) Visual Fortran,版本 16.0 内部版本 20160415:
ifort -Od -debug:all -check:all -traceback reader.f90
- NAG Fortran 编译器版本 6.1(Tozai) Build 6116:
nagfor -O0 -g -C reader.f90