[前へ]   [目次へ]   [次へ]

エラーと警告(4)(C/C++)


今回は実行時エラーチェックについてです。

プログラムの実行中には様々な要因により大小さまざまなエラーが発生します。
発生したエラーは状況によって影響が変わってきますが、
よほどのことがない限りエラーはプログラム中でチェックすることができます。

エラーが発見された時、どう対処するかはプログラムが決めることができます。
また、プログラム側で対処しない場合、無視されるか強制終了されるかのどちらかです。

今回はエラーが発生したかどうかをチェックする手段についてです。

エラーのチェック方法はエラーの種類によって、何通りかのパターンがあります。
基本的にはエラーの種類、それぞれの仕様に合わせたやり方でないとチェックできません。

一つ目のパターンは、関数の戻り値(呼び出し結果)に示される場合です。
何らかの要因により、関数が失敗したり、関数内でエラーが発生した場合等でこのパターンがよく使われます。
どんな値がエラーかは、関数の仕様なので関数ごとに異なります。
関数によっては返された値でエラーの種類まで示している場合もあります。
例えば、 printf 関数の場合、戻り値が負数の場合はエラー発生とされています。

また、戻り値によって詳細なエラーが示されない場合、
詳細なエラー情報がグローバル変数等のどこからでもアクセス可能な場所に保存されるものがあります。
このタイプで詳細を得る場合は、指定された変数等を調べます。
基本的にエラー発生時しか設定されないものが多いため、試行前にもチェックしておかないと最初からその値なのか、
新しく設定されたものか区別がつかないことがあります。
また、唯一の場所に保存されていくため、すぐに調査しないと値が変わってしまう場合があります。
標準ライブラリでは errno というグローバル変数が使用されます。
たまにエラーではないものを設定する関数もあります。


二つ目のパターンは、シグナルを使って割り込まれるパターンです。
このパターンで報告されるエラーは重大なものが多く、正常に復帰できる可能性が低めです。
特に設定しない場合はそのまま強制終了されます。
ちなみにコンソールアプリでのCtrl+Cはこれをユーザーが投入する方法だったりします。
実は私はこのパターンのエラーをチェックしたことがないのであまり詳しくないのですが(汗)


三つ目のパターンは、例外を使って割り込まれるパターンです。
このパターンはC++のみで使用できます。
チェックするには try ブロックを構築する必要があり、
例外が投入されると try ブロックがあるところまで一気に return されます。
メモリに関するエラーの時にこのパターンが使われるケースが多いです。
また、 main 関数から、または main 関数まで戻っても try ブロックがない場合に例外によって return されると、強制終了します。


これは少しエラーとは異なりますが、 assert によって終了される場合もあります。
assert はプログラムのある位置で「必ずこうなるはず」という条件をチェックするために使われます。
条件分岐のようなものですが、偽になるとメッセージを出して終了されます。

デバッグ用なので基本的には完成したら無効にします。
そのため assert には1行書くとソース中の全ての assert を無効にする方法が提供されています。
また、偽になったときの動作は変更できません。


大抵はこれらのいずれかの方法でエラーが通知されます。
受け取ったエラーをどう処理するか(無視、修正、終了など)は状況によって個別に決定します。

[前へ]   [目次へ]   [次へ]

プログラミング講座 総合目次

最終更新 2008/10/17