FreeBASIC マニュアルのトップに戻る

FreeBASIC ProPgErrorHandling

目次→教本→プログラマーのための案内Error Handling←オリジナル・サイト

エラー処理 左にメニュー・フレームが表示されていない場合は、ここをクリックして下さい

←リンク元に戻る プログラム開発関連に戻る

実行時エラーを、扱います。

FreeBASIC は、以下の方法で、誤りを扱うことができます:


注意: エラーが、OS の一般保護障害(例えば、プログラムがプロセスメモリ領域の外に書く)を生じない場合、以下の情報は有効です。
この場合は、OSは、すぐに、プログラムを止めて、エラーを発生するでしょう:
FreeBASIC の中から、それを避けることは、できません。

デフォルトエラー処理操作

デフォルトの FreeBASIC の振舞いは、ERR 変数を設定して、そして、処理を続けることになっています。

Dim As Integer e
Open "xzxwz.zwz" For Input As #1
e = Err
Print e
Sleep


(上のプログラム例は、xzxwz.zwz ファイルが無いことを想定しています。)
プログラムは止まりません。プログラムは、ERR 変数を設定して、続きます。
次の行で、エラーを処理できます。

いくつかの IO 関数(OpenPut #... など)は、関数フォームを使って、エラー番号を返すか、または、うまく行ったときはゼロを、返すことができます。

Print Open ("xzxwz.zwz" For Input As #1)
Sleep



QuickBasic 風のエラー処理操作

-e, -ex または -exx スイッチを使ってコンパイルすると、プログラムは QB 風のエラーハンドラが有効になります。
どのハンドラーもエラーを処理しないと、プログラムはエラーで停止します。

注意: QB 風のエラー処理を使うと、プログラマは、すべてのエラー条件について、対処する準備が必要になります。

'' QB (-lang qb) 方言で、コンパイルします

'$lang: "qb"

On Error Goto FAILED
Open "xzxwz.zwz" For Input As #1
On Error Goto 0
Sleep
End

FAILED:
Dim e As Integer
e = Err
Print e
Sleep
End



On Error は、エラーが見つかったとき、プログラムがエラー処理ルーチンにジャンプする、エラー処理操作を、セットします。
On Error Goto 0 は、エラー処理を無効にします。

エラー処理ルーチンが設定されないと、誤りが発生したとき、プログラムは、止まって、エラーメッセージを実行画面に送ります。
Aborting program due to runtime error 2 (file not found)

 
QBのように、エラー処理対応ルーチンは、プログラムの最後に、置くことができます。
On Local Error 命令は、ローカルのエラー処理操作ルーチンを、誤りが発生する SubFunction の最後に設定できるようにします。

'' -e で、コンパイルします
'' -e コマンドライン・オプションは、エラー処理を可能にするのに必要です。

Declare Sub foo
  foo
Sleep

Sub foo

    Dim filename As String
    Dim errmsg As String
    filename = ""
    On Local Error Goto fail
  Open filename For Input Access Read As #1
    Print "No error"
    On Local Error Goto 0
    Exit Sub

  fail:
  errmsg = "Error " & Err & _
           " in function " & *Erfn & _
           " on line " & Erl
  Print errmsg

End Sub


-e スイッチを使うと、エラー処理操作は、プログラムを終了しなければなりません。(-lang 方言がどうであれ)
-ex または -exx)かつ -lang qb 方言の場合、エラールーチンは Resume (エラーの原因となった命令文を再試行)または Resume Next (次の命令から続行)を使って終了できます。

エラー・コード

実行時エラー番号のリストと、その意味については、実行時エラー・コード を参照ください。

ユーザ・エラー・コード範囲は定義されていません。
Error を、エラーコード設定に使うときは、大きい値を使って、内蔵のエラーコードのリストとの衝突を避けると、良いでしょう。
(この内蔵のリストは、将来、拡張されるかもしれません。)


'On [Local] Error Goto' 命令文の使い方
'On [Local] Error Goto label' は、エラーが発生した時点で、指定したラベルにプログラムがジャンプするようにします。このようなエラーは、'Open', 'Get', 'Put', などの組み込み命令文や、Error 命令文が使われたときに発生します。
組み込み文のエラーチェックは、プログラムが -e, -ex, -exx のいずれかのオプションでコンパイルされている場合にのみ有効です。それ以外の場合は、ジャンプは行われませんが、コマンドはプロセッサ時間を消費します。
Error 命令文だけで起動された場合、'On [Local] Error Goto label' は、これらのコンパイルオプションがいずれも使われていなくても、常に動作したままです。
'On Error Goto 0' は、現在のエラー・ハンドラを無効にします。エラーが発生しても、FreeBASIC はジャンプしません。

オプションの Local キーワード(Sub/Function 内でのみ許可)は、'On Local Error' があるのと同じ手続き内でのみエラーハンドラを定義するために使われることを意図していました(例えば、PDS 7.1 や VB Dos 1.0 との互換性のため)。この場合、FreeBASIC は現在の手続き内のみでラベルを検索するはずでした。
しかし、現在では、Local 節はコンパイラによって無視され、エラー・ハンドラは、'On [Local] Error' があるのと同じ手続きの範囲内か、モジュールのメイン部分(手続きの前に定義されている場合)のどちらかになります。
例外として、-gen gcc (または fbc 64-bit) を使う場合、Local 節は正しく考慮されるようですが、ローカル範囲内は例外です。

'On [Local] Error Goto label' は、関数形式の構文が利用できる場合、組み込み手続きからのエラーを捕捉するには最適な方法ではありません。戻り値のエラーコードで、直接テストできます(関数から返されたエラーコードを使うと、QuickBASIC のようなエラーチェックや命令文 'On Error Goto' が禁止されます)。

デバッグで -exx オプションを使ってプログラムをテストすることは非常に役に立つため、-lang fb 方言で -exx オプションに対応したプログラムを書くことを推奨します:
- ResumeResume Next 命令文は -lang fb では全くサポートされていない(コンパイルエラー)ので、使わないようにしましょう。
- 一方、'On [Local] Error Goto' 命令文は、有用な場合(関数の形式が利用できない場合)もあります。-e, -ex, -exx の中の任意のオプションで実行されます。
それ以外の場合(エラーチェックのオプションがない場合)、'On [Local] Error Goto' は非アクティブ(コンパイルエラーなし)ですが、CPU時間を消費します。

このため、必要に応じて、通常は QuickBasic のようなエラー処理('On [Local] Error Goto label' ..... 'label:' .....)を記述し、__FB_ERR__ の値に応じた条件付きのアセンブリ指令を行い、実行速度(エラーチェック・オプションを使わない場合)に不利にならないようにします。

コンパイル・オプション(無し, -e/-ex/-exx)に関する 'On Error Goto' (-lang fb) 命令文の動作を、いくつかの例 (4) を含む次のプログラムで説明します。エラーチェック・オプション有無でコンパイルします(4*2=8 テスト):

#DEFINE Config 1
'#DEFINE Config 2
'#DEFINE Config 3
'#DEFINE Config 4



#IF Config = 1 '-----------------------------------------------------------

Open "does_not_exist" For Input As #1

Print "main end"
Sleep
System

' - with compiler option 'none' :
'     console output :
'       'main end'
'
' - with compiler option '-e' or '-ex' or '-exx' :
'     console output :
'       'Aborting due to runtime error 2 (file not found) at line 10 of .....'

#ENDIF '-------------------------------------------------------------------



#IF Config = 2 '-----------------------------------------------------------

Dim As Integer Result = Open("does_not_exist" For Input As #1)
If Result <> 0 Then
    Print "error code returned: " & Result
    Print "file not found (processed by 'Result = Open(.....)')"
End If

Print "main end"
Sleep
End

' - with compiler option 'none' or '-e' or '-ex' or '-exx' :
'     console output :
'       'error code returned: 2'
'       'file not found (processed by 'Result = Open(.....)')'
'       'main end'

#ENDIF '-------------------------------------------------------------------



#IF Config = 3 '-----------------------------------------------------------

On Error Goto Error_Handler
Open "does_not_exist" For Input As #1

Print "main end"
Sleep
End

error_handler:
Print "file not found (processed by 'On Error Goto')"
On Error Goto 0
Print "QB-like error handling end"
Sleep
End

' - with compiler option 'none' :
'     console output :
'       'main end'
'
' - with compiler option '-e' or '-ex' or '-exx' :
'     console output :
'       'file not found (processed by 'On Error Goto')'
'       'QB-like error handling end'

#ENDIF '-------------------------------------------------------------------



#IF Config = 4 '-----------------------------------------------------------

On Error Goto error_handler
Dim As Integer Result = Open("does_not_exist" For Input As #1)
If Result <> 0 Then
    Print "error code returned: " & Result
    Print "file not found (processed by 'Result = Open(.....)')"
End If

Print "main end"
Sleep
End

error_handler:
Print "file not found (processed by 'On Error Goto')"
On Error Goto 0
Print "QB-like error handling end"
Sleep
End

' - with compiler option 'none' or '-e' or '-ex' or '-exx' :
'     console output :
'       'error code returned: 2'
'       'file not found (processed by 'Result = Open(.....)')'
'       'main end'

#ENDIF '-------------------------------------------------------------------

Config=2 と Config=4 のセクションは、FB 関数が明示的に返されたエラーコードを使って呼び出された場合(-lang fb dialect)、エラーチェックのレベル('無し'、'-e'、'-ex'、'-exx')に関わらず、'On Error Goto' がバイパスされることを強調しています。

参照:

プログラマーのための案内に戻る
目次に戻る
←リンク元に戻る プログラム開発関連に戻る

ページ歴史:2020-06-28 14:58:05
日本語翻訳:WATANABE Makoto、原文著作者:JeffMarshall

ホームページのトップに戻る

表示-非営利-継承