[実験] 局所的な例外処理

C++の例外処理は便利なのですが、決して軽量とはいえませんし、オーバースペックな場合も少なくありません。今回は、非局所分岐をあきらめて、同じ関数内に限定した局所的例外処理の実験を行ってみます。

まずはサンプルコードからです。

#include <stdio.h>
 
#define try_      goto eXcePtIoN_tRy; if (0) eXcePtIoN_tRy:
#define catch_(e) else if (0) eXcePtioN_##e:
#define throw_(e) goto eXcePtioN_##e
 
int main(void)
{
  try_
  {
    puts("begin");
 
    int value = 0;
    scanf("%1d", &value);
    switch (value)
    {
    case 1:
      throw_(test1);
    case 2:
      throw_(test2);
    }
 
    puts("end");
  }
  catch_(test1)
  {
    puts("test1");
  }
  catch_(test2)
  {
    puts("test2");
  }
  return 0;
}
 

何をやっているかは、特に説明は必要ないでしょう。工夫した点としては、例外処理用のラベル名を汚くすることで、ユーザー定義の一般識別子とバッティングすることを回避したのと、同じ関数内でtry_ブロックを複数指定できないようにしたことです。

同じ関数内でtry_ブロックを複数指定できないのは一見不便なようですが、通常、try_ブロックが複数必要になるケースはそう多くありません。また、仮にtry_ブロックを複数作ることを許してしまうと、gotoで実現している関係上、別のtry_ブロックのcatch_節に飛べてしまったりすることになり、いろいろ問題が出てきます。

このサンプルの手法は、CでもC++でも同じように使えます。C++で使った場合、try_節で定義した局所オブジェクトは、throw_で抜ける際にそのデストラクタが呼び出されます。

この記事のトラックバックURL:

http://www.kijineko.co.jp/trackback/487