web-dev-qa-db-ja.com

Fortranには例外処理がありますか?

Pythonのように、Fortranに例外処理構造はありますか?

try:
    print "Hello World"
except:
    print "This is an error message!"

存在しない場合、例外を処理する最も簡単な方法は何ですか?

13
Cafer Cruz

このような例外は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に準拠したコンパイラが必要であることに注意してください。

私はこのようなものを見たことはありませんが:)

11
Alexander Vogt

次のFortran規格に例外処理を追加する提案があります(下記のSteve Lionelのコメントを参照)。例はこちらをご覧ください 例外処理-BCS Fortranスペシャリストグループ

これは明らかにFortranで長い歴史があります(以下でもSteveの2番目のコメントを参照)

3
King

そのことを考えると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機能を実現することもできます。

P.S。例のソース here および here

2
Foad

これは適切な「例外処理」ではありませんが、次のサブルーチンが実際に役立つことがわかりました

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)を使用してコンパイルされている場合、コードは停止されます(サブルーチンでゼロによる意図的な除算が行われるため)およびコールスタック印刷されます。さらに、コードをデバッグしている場合、(実行が停止されていても)プロセスは強制終了されないため、デバッガー内から変数やコールスタックなどを探索できます。

0
Paolo M