跳轉到內容

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

華夏公益教科書