Fortran/错误处理
通常在错误情况下,您的程序将停止,您将收到错误消息。唯一的例外是,在 read
和 write
语句的括号控制列表的末尾,您可以添加 err=label
来确定在发生错误时跳转到的行。
现代 Fortran(从 Fortran 90 开始)引入了四个主要错误捕获区域。
1) 文件处理和 i/o 操作错误处理
2) IEEE 浮点数错误检测和报告
3) 动态分配
4) 命令行操作
所有外部文件处理语句和 I/O 操作(open
、read
、write
、close
、inquire
、backspace
、endfile
、flush
、rewind
和 wait
)现在可以接受可选的 iostat
和 iomsg
子句。iostat
是一个整数,如果出现错误,它将返回一个非零值,在这种情况下,分配给 iomsg
的字符变量将返回一个简短的错误消息。非零整数和消息是编译器相关的,但内在模块 iso_fortran_env
提供了访问两个重要值的途径:iostat_end
和 iostat_eor
。如果发生错误,并且 iostat
非零,则执行将不会停止。ERR 子句仍然支持,但不应使用。
integer :: my_iostat
character (256) :: my_iomsg
open (file='my.dat', unit=10, iostat=my_iostat, iomsg=my_iomsg)
if (my_iostat/=0) then
write (*,*) 'Open my.dat failed with iostat = ', my_iostat, ' iomsg = '//trim(my_iomsg)
end if
请注意,消息字符所需的长度取决于供应商和错误。
这是一个很大的话题,但本质上,现代 Fortran 提供了访问三个内在模块:IEEE_arithmetic
、IEEE_exceptions
和 IEEE_features
。这些功能可用于截取除以零和溢出等错误,但会牺牲一些性能。
IEEE_features
模块通过在程序员放置 use 语句的范围单元中使用关联来控制对程序员可能需要的功能的访问,
subroutine blah
use, intrinsic :: ieee_features
! ...
end subroutine blah
参见 Metcalf 等人编著的《现代 Fortran 解释》 (Modern Fortran Explained) 的第 11 章,牛津大学出版社。所有必要的基本设施都存在,以便程序员可以根据需要构建 try/catch 系统。
现代 Fortran 允许对任何类型的数组进行运行时分配和释放,典型的错误可能是尝试动态分配一个太大的数组,以至于没有足够的内存,或者尝试释放一个尚未分配的数组。存在可选的 stat
和 errmsg
子句,可用于防止程序失败,并允许程序员采取回避措施。
real, allocatable, dimension (:) :: x
integer :: my_stat
character (256) :: my_errmsg
allocate (x(100000000), stat=my_stat, errmsg=my_errmsg)
if (my_stat/=0) then
write(*,*) 'Failed to allocate x with stat = ', my_stat, ' and errmsg '//trim(my_errmsg)
end if
这些功能在等效的 coarray 功能中可用。
现代 Fortran 还支持对命令行操作执行的错误检测,
integer :: my_cmdstat
character (256) :: my_cmdmsg
call execute_command_line('my.exe', cmdstat=my_cmdstat, cmdmsg=my_cmdmsg )
if (my_cmdstat/=0) stop
在此示例中,my.exe 程序的程序员负责返回哪些代码以及公开哪些错误消息,但 -1 和 -2 保留用于允许编译器供应商指示哪些功能可能受支持。