2

私はSEHでいくつかの実験をしていました。私のコードでは、エラーの原因となるブロックを __try 句に記述し、ハンドラーを __except() に記述しました。

__try{
Test *pTest = 0;
int k = pTest->GetValue();
cout << "continue after exception" << endl;
}
__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION,EXCEPTION_EXECUTE_HANDLER)
{
 cout << "caught!!" << endl;
}
cout << "Exception handled" << endl;

__except() の 2 番目のパラメーターは、次のいずれかです。

EXCEPTION_CONTINUE_SEARCH 例外は認識されません。最初に try-except ステートメントを含むハンドラー、次に優先順位の高いハンドラーのスタックを検索し続けます。

EXCEPTION_CONTINUE_EXECUTION 例外は認識されますが、無視されます。例外が発生した時点で実行を続行します。

EXCEPTION_EXECUTE_HANDLER 例外を認識しました。__except 複合ステートメントを実行して例外ハンドラーに制御を移し、例外が発生した時点で実行を継続します。

EXCEPTION_CONTINUE_EXECUTION/EXCEPTION_EXECUTE_HANDLER を使用すると、例外発生時点で実行が継続されません (例外発生時点の意味を誤解している可能性があります)。デバッグモードで実行すると、出力は

caught
Exception handled

リリースモードで実行すると、出力は

continue after exception
Exception handled

なぜ動作が異なるのか理解できませんでした。誰でも助けてください。

4

2 に答える 2

4

@Joachim は、コンマ演算子の問題について正しく指摘しています。

私は、次の__except()ように見えるはずだと思います:

__except((GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION) ?
         EXCEPTION_EXECUTE_HANDLER :
         EXCEPTION_CONTINUE_SEARCH)

これにより、例外がアクセス違反の場合に例外ハンドラが実行されます。そうでない場合、例外は、最も近いアウター__try(存在する場合) まで伝播します。

それpTestはクラスへのポインターであり、実行するために逆参照する必要がないのではないかと心配してGetValue()います。コンパイラーは、リリースモードで最適化が有効になっていることを認識します。またはGetValue()、役に立たないと見なされ、それを呼び出すためのコードが生成されない場合もあります。また、NULL ポインターを逆参照すると未定義の動作が発生することをコンパイラーが認識し、コンパイル時にコードをねじ込んで罰することを決定する可能性もあります。コンパイラーには、それを行うすべての権利があります。たとえば、gccはそれを行うことで有名です。

于 2013-02-26T11:10:47.260 に答える
1

表現

GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION,EXCEPTION_EXECUTE_HANDLER

あなたが期待することをしません。GetExceptionCode()の結果をと比較しますEXCEPTION_ACCESS_VIOLATIONが、式全体の結果は ですEXCEPTION_EXECUTE_HANDLER

ウィキペディアでコンマ演算子の詳細を参照してください。

あなたがしたいことは、おそらく次のとおりです。

GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION || GetExceptionCode() == EXCEPTION_EXECUTE_HANDLER
于 2013-02-26T11:03:09.637 に答える