実行時エラー処理の簡単な実装

実行時エラーとは実行したときに起こりうるエラーのことで,例えばメモリが確保できなかったとか,変な実行時引数 (argv) が与えられたとかいったエラーのこと.実行時エラーが発生した場合はその時点でプログラムを終了させるべきである.

実行時エラー処理をしないとバグを見付けにくくなるので必ずすべきであるが,しかし,それはめんどい作業である.簡単に assert() 関数で書いてしまえば楽であるが,これは本来の assert() 関数の使いかたではない.本来この assert() 関数はプログラム上の表明を表現するために使われるからだ.しかも、assert() 関数はマクロ NDEBUG が定義されると無効となってしまう.ならばそこで,実行時の表明を作ってしまえばよいではないか.ということで簡単に実装.

#define runtime_assert(expr) runtime_assert_(expr, #expr)
void runtime_assert_(bool expr, const char* mes)
{
  if (!expr){
    cerr << ":runtime-assertion '" << mes << "' failed." <<endl;
    abort();
  }
}

実装はほとんど assert() 関数と同じ.これで,手軽に実行時エラー処理を書くことができる.

// 引数に自然数を2つ渡す
int main(int argc, char **argv){
  if (ac<3)
    exit(0);
  runtime_assert(atoi(argv[1])>=0 && atoi(argv[2])>=0);
  func(atoi(argv[1]), atoi(argv[2]));
}

こういうプログラムに次ようなのコマンド

$ ./a.out -10 10

を渡すと、以下のように実行時エラーを起こしてとまる。

$ :runtime-assertion 'atoi(argv[1])>=0 && atoi(argv[2])>=0' failed.
アボートしました

もちろん、簡単な実装なので欠点もある。それは、何のエラーなのか説明がないのでユーザには何が起こったかわからないことだ。この実装は、実験プログラムなどの簡単でソースコードが読めるプログラムでは効果を発揮するでしょう。ようするに、手抜きができるエラー処理の場合にのみ使えってことです。