いけむランド

はてダからやってきました

libexception


使用例を参考にして、自分でも書いてみたが、ちょっと使いにくい点もありそう。

  • マクロが for 文の中で変数宣言しているため、gcc でのコンパイルには -std=c99 オプションが必要となる。
  • finally は「例外の有無に関わらず必ず」実行されるのではなく「except 節で処理されなかった例外であった場合に」実行される。
  • 例外の種類は内部では int で扱われるため、特定の例外クラスのサブクラスはすべて処理するような except 節は書けない。
    • 共通処理関数を各 except 節で呼び出すようにしないといけない。
#include <stdio.h>
#include <stdlib.h>
#include <exception.h>

typedef enum {
  StringIndexOutOfBoundsException,
  FileNotFoundException,
  IllegalStateException,
} Exception;

static char charAt(char* str, int index)
{
  if (index < 0 || index >= strlen(str)) {
    throw(StringIndexOutOfBoundsException, "StringIndexOutOfBoundsException");
  }
  return str[index];
}

static FILE* openFileForReading(char* filename)
{
  FILE* fp;
  if ((fp = fopen(filename, "r")) == NULL) {
    throw(FileNotFoundException, "FileNotFoundException");
  }
  return fp;
}

static void handlerForRuntimeException()
{
  puts("handlerForRuntimeException");
}

int main(int argc, char** argv)
{
  try {
    charAt("Hello, world!", 1);
    openFileForReading("foo.txt");
    throw(IllegalStateException, "IllegalStateException");
  } except {
    on (StringIndexOutOfBoundsException) {
      handlerForRuntimeException();
      exception_dump(STDERR_FILENO);
    }
    on (FileNotFoundException) {
      handlerForRuntimeException();
      exception_dump(STDERR_FILENO);
    }
    finally {
      exception_dump(STDERR_FILENO);
    }
  }
}
% gcc exception.c -std=c99 -lexception
% ./a.exe
handlerForRuntimeException
at exception.c:39 in main():
at exception.c:23 in openFileForReading(): FileNotFoundException (1)
%