Fortran/エラーの捕捉
通常、エラーが発生すると、プログラムは停止し、エラーメッセージが表示されます。ただし、read
とwrite
文の括弧付き制御リストの末尾に、err=label
を追加することで、エラー発生時にジャンプする行を指定できます。
現代のFortran(Fortran 90以降)では、主に次の4つのエラー捕捉領域が導入されています:
- ファイル処理とI/O操作のエラー処理
- IEEE浮動小数点エラーの検出と報告
- 動的割り当て
- コマンドライン操作
ファイル処理とI/O操作
編集すべての外部ファイル処理文および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
メッセージ文字の必要な長さは、ベンダーおよびエラーに依存します。
IEEE浮動小数点エラーの検出と報告
編集これは大きなトピックですが、本質的には、現代のFortranは3つの組込みモジュールIEEE_arithmetic
、IEEE_exceptions
、およびIEEE_features
へのアクセスを提供します。これらの機能を使用して、ゼロで割るエラーやオーバーフローなどのエラーを検出できますが、その代わりにパフォーマンスが若干低下します。
IEEE_features
モジュールは、プログラマが必要とする機能へのアクセスを制御し、プログラマが使用ステートメントを配置するスコープユニットでの使用関連付けによって制御されます。
例
編集subroutine blah use, intrinsic :: ieee_features ! ... end subroutine blah
Metcalfらによる『Modern Fortran Explained』(OUP)の第11章を参照してください。プログラマが望む場合には、必要な基本的な機能がすべて揃っており、try/catchシステムを構築することができます。
- 訳註
- Fortranでは、組み込みモジュールIEEE_arithmetic、IEEE_exceptions、およびIEEE_featuresを使用して、try-catchの機能を模倣することができます。以下に、簡単な例を示します。
program try_catch_example use ieee_arithmetic, only: ieee_is_nan implicit none real :: result integer :: status ! Try result = divide(10.0, 0.0, status) ! Check for error if (status /= 0) then print *, "Error occurred during division operation." else print *, "Result of division: ", result end if contains ! Custom division function real function divide(dividend, divisor, status) real, intent(in) :: dividend, divisor integer, intent(out) :: status if (ieee_is_nan(divisor)) then status = 1 ! Indicate divide by zero error divide = 0.0 ! Return 0 as result else status = 0 ! No error divide = dividend / divisor end if end function divide end program try_catch_example
- この例では、
ieee_arithmetic
モジュールからieee_is_nan
関数を使用して、ゼロで割るエラーを捕捉しています。status
変数を使用してエラー状態を示し、それに応じて処理を行っています。このように、Fortranでは独自のエラーハンドリング機構を実装することができます。
- この例では、
動的割り当て
編集現代の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
これらの機能は、等価の共配列機能でも利用できます。
コマンドライン操作
編集現代の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は、コンパイラベンダーがサポートされる機能を示すために予約されています。