2011年6月22日水曜日

VC++ 例外コンパイラオプション

プログラムを組む時、例外オプションには、結構 /EHsc を使う事が多かったんですが、ここんところサーバ系のプログラミングで、以前では生じなかったような Access Violation が頻出しました。SelectObject( HBITMAP ) を2回連続で実行すると、HBITMAP の内容が破壊される事があるという現象に対応して、まぁ、以前からあった割と初歩的な変数の初期化ミスなんかが表面化したというのもあります。
コードは、変わってないのに致命的に落ちる事が多くなったな?と思って、考え巡らしていたところ、例外機構の処理が関係するんじゃないか?なんて啓示がありまして、こんなコードを追試してみました。

x.cpp
#include <iostream>

class A {
public:
  A() { std::cout << "A()" << std::endl; }
  ~A() { std::cout << "~A()" << std::endl; }
};

int main() {
  int* n = 0;
  try {
    A a;
    *n = 3;
  } catch(...) {
    std::cerr << "catch" << std::endl;
  }
  return 0;
}

これに対して cl /EHsc /GR /MD x.cpp
C:\MyWorks>x
A()
で、あぼーん

一方 cl /EHa /GR /MD x.cpp
C:\MyWorks>x
A()
~A()
catch
で、めでたし。

普通は、/EHa を使う方がいいのねん。
とまぁ、こんな初歩的なコンパイラ・オプションにまつわるお話でした。

2011/08/23 追記: Windows2003 までは、DCOM におけるアプリケーション例外は、スレッドからサービスに影響する事がありませんでした。Windows2008 からは、キャッチされなかった例外は、即サービス停止に繋がるようになりました。

0 件のコメント: