コストラクタ、デストラクタ、例外安全

例外が関数から外に出ようとすると、localなオブジェクトは破棄されてから関数の外に出るなんて話はよく聞きますが・・・。じゃぁ、破棄されるタイミングで例外が発生したらどないすんねん?

#include <iostream>
using namespace std;

class T {
public:
  T() { cout << "constructor" << endl; }
  ~T() { cout << "destructor" << endl; throw 1; }
};

void f() {
  T t;
  throw 0;
}

int main()
{
  try {
    f();
  } catch(int a) {
    cout << "catch " << a << endl;
  }
}

実行結果。

% ./a
constructor
destructor
zsh: abort (core dumped)  ./a

ぉーん。
調べる前に実験するのはよくないですね。Microsoftの解説によれば、デストラクタでの例外スローはプログラム停止。ついでに、コンストラクタで例外投げるのもやめろと。コンストラクタでも例外投げるなとなると、bad_allocが発生するような処理も書くなと言うことか。結局、validフラグみたいなのを作って、適当にifでチェックしないといけないんですかね。