次のコード:
- gcc バージョン 4.4.5 (Ubuntu/Linaro 4.4.4-14ubuntu5/32bits) でコンパイルすると問題なく動作します。
- MSVC10 (Win7/32 ビット) でコンパイルすると正常に動作します。
- gcc バージョン 4.5.2 (Win7/32 ビットの MinGW) で実行するとクラッシュする
main.cpp :
# include <iostream>
# include <csetjmp>
# include <stdexcept>
using namespace std ;
void do_work(jmp_buf context)
{
try
{
throw runtime_error("Ouch !") ;
}
catch(exception & e)
{
}
longjmp(context, -1) ; //BP1
}
int main(int, char *[])
{
jmp_buf context ;
try
{
if( setjmp(context) != 0 )
{
throw runtime_error("Oops !") ; //BP2
}
do_work(context) ;
}
catch(exception & e)
{
cout << "Caught an exception saying : " << e.what() << endl ;
}
}
デバッグしてみましたが、プログラムの動作がおかしくなりました。場合によっては、最初のブレークポイント (BP1) を通過して BP2 でクラッシュし、プログラムが無限ループに陥った場合のように、制御が BP1 に到達しないこともあります。私のデバッグスキルではこれ以上は言えません。
このコードは、MinGW 4.5 で奇妙な動作を示す最小限のものです。また、次のことに気付きました。
do_work関数呼び出しをその内容で置き換えると、プログラムは正常に実行されます。try{ ... } catch(...){ }内のブロックを削除するdo_workと、プログラムは正常に実行されます。- 最適化フラグは効果がありません (常にクラッシュします)。
C++ コードの問題は認識してsetjmp/longjmpいますが、一部のレガシー C コードとのインターフェイスに使用せざるを得ません。
私の質問 :
- これは欠陥/バグ/エラーコードですか? または、MinGW 4.5 がコードを誤って処理していますか? (ツールのせいにするのは辛辣でおこがましいですが、いくつかの設定に問題があるのではないかと思います)。
アドバイスをありがとう。
必要に応じてタグを付け直してください。