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 保留用於允許編譯器供應商指示哪些功能可能受支援。