跳转到内容

Fortran/错误处理

来自维基教科书,自由的教科书

通常在错误情况下,您的程序将停止,您将收到错误消息。唯一的例外是,在 readwrite 语句的括号控制列表的末尾,您可以添加 err=label 来确定在发生错误时跳转到的行。

现代 Fortran(从 Fortran 90 开始)引入了四个主要错误捕获区域。

1) 文件处理和 i/o 操作错误处理

2) IEEE 浮点数错误检测和报告

3) 动态分配

4) 命令行操作

文件处理和 I/O 操作

[编辑 | 编辑源代码]

所有外部文件处理语句和 I/O 操作(openreadwritecloseinquirebackspaceendfileflushrewindwait)现在可以接受可选的 iostatiomsg 子句。iostat 是一个整数,如果出现错误,它将返回一个非零值,在这种情况下,分配给 iomsg 的字符变量将返回一个简短的错误消息。非零整数和消息是编译器相关的,但内在模块 iso_fortran_env 提供了访问两个重要值的途径:iostat_endiostat_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

请注意,消息字符所需的长度取决于供应商和错误。

IEEE 浮点数错误检测和报告

[编辑 | 编辑源代码]

这是一个很大的话题,但本质上,现代 Fortran 提供了访问三个内在模块:IEEE_arithmeticIEEE_exceptionsIEEE_features。这些功能可用于截取除以零和溢出等错误,但会牺牲一些性能。

IEEE_features 模块通过在程序员放置 use 语句的范围单元中使用关联来控制对程序员可能需要的功能的访问,

subroutine blah
    use, intrinsic :: ieee_features
    
    ! ...
end subroutine blah

参见 Metcalf 等人编著的《现代 Fortran 解释》 (Modern Fortran Explained) 的第 11 章,牛津大学出版社。所有必要的基本设施都存在,以便程序员可以根据需要构建 try/catch 系统。

动态分配

[编辑 | 编辑源代码]

现代 Fortran 允许对任何类型的数组进行运行时分配和释放,典型的错误可能是尝试动态分配一个太大的数组,以至于没有足够的内存,或者尝试释放一个尚未分配的数组。存在可选的 staterrmsg 子句,可用于防止程序失败,并允许程序员采取回避措施。

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 保留用于允许编译器供应商指示哪些功能可能受支持。

华夏公益教科书