[実験] 局所的な例外処理
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;
}
#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
