Pythonのように、Fortranに例外処理構造はありますか?
try:
print "Hello World"
except:
print "This is an error message!"
存在しない場合、例外を処理する最も簡単な方法は何ですか?
このような例外はFortranには存在しないため、例外処理はありません。
しかし、標準のFortranを使用して例外処理と同様のことを行うことができます。それについての論文さえあります Arjen Markus、 "Fortranでの例外処理" 。
最も一般的な表記は、エラーコードを示す(整数)戻り変数を使用することです。
subroutine do_something(stat)
integer :: stat
print "Hello World"
stat = 0
end subroutine
そしてメインプログラムで
call do_something(stat)
if (stat /= 0) print *,"This is an error message!"
エラーメッセージを格納することもできる例外の専用の派生型を定義するなど、このペーパーで説明されている他の方法があります。例外に最も近づくここで言及された例は、サブルーチンの代替リターンを使用しています(ただし、関数では不可能です)。
subroutine do_something(stat, *)
integer :: stat
!...
! Some error occurred
if (error) return 1
end subroutine
そしてメインプログラムで
try: block
call do_something(stat, *100)
exit try ! Exit the try block in case of normal execution
100 continue ! Jump here in case of an error
print *,"This is an error message!"
end block try
ブロック構造にはFortran 2008に準拠したコンパイラが必要であることに注意してください。
私はこのようなものを見たことはありませんが:)
次のFortran規格に例外処理を追加する提案があります(下記のSteve Lionelのコメントを参照)。例はこちらをご覧ください 例外処理-BCS Fortranスペシャリストグループ
これは明らかにFortranで長い歴史があります(以下でもSteveの2番目のコメントを参照)
そのことを考えるとtry-except
ユースケースはI/O処理用であり、すべてのFORTRAN I/O関数には、エラーが発生した場合に行ラベルを指すERR
指定子があることを知っておく必要があります。例えば:
C2345678
READ( UNIT=5, FMT=10, ERR=30, IOSTAT=N ) X
10 FORMAT(I5)
WRITE( UNIT=6, FMT=20, ERR=30, IOSTAT=N ) X
20 FORMAT(I5)
30 WRITE( *, * ) 'I/O error # ', N, ', on 1'
もちろん、WRITE
実行可能ファイルを他の式に置き換えて、何らかの形式のexcept
機能を実現することもできます。
これは適切な「例外処理」ではありませんが、次のサブルーチンが実際に役立つことがわかりました
SUBROUTINE RAISE_EXCEPTION(message)
INTEGER i
CHARACTER(LEN=*) message
PRINT *,message
i=1
i=1/(i-i)
ENDSUBROUTINE
エラー状態が発生したときに呼び出すことができます。
IF (var<0) CALL RAISE_EXCEPTION('Error: var should be positive!')
コードがgfortran -ffpe-trap=zero
および-fbacktrace
オプション(-fpe0
with ifort)を使用してコンパイルされている場合、コードは停止されます(サブルーチンでゼロによる意図的な除算が行われるため)およびコールスタック印刷されます。さらに、コードをデバッグしている場合、(実行が停止されていても)プロセスは強制終了されないため、デバッガー内から変数やコールスタックなどを探索できます。