web-dev-qa-db-ja.com

__try / __exceptブロックまたはtry / catchブロックのどちらを使用するのが良いですか?

スローした例外をキャッチするためのより良い方法はどれなのかと思います。それは__try/__exceptブロックですか、try/catchブロックですか

私はC++で書いていますが、プログラムはWindowsでのみ使用されるため、移植性は問題になりません。

ありがとう!

27
Zain Rizvi

try/catchブロックを使用する必要があります。

他の人がすでに答えているように、__try/__exceptは、一般的な例外をキャッチするためではなく、SEH(ウィンドウで生成されたエラー)をキャッチするためのものです。

最も重要なことは、__try__catchは、例外がスローされたときにC++デストラクタを実行したり、スタックを正しく巻き戻したりしない可能性があることです。

まれな場合を除いて、SEHの例外をキャッチしようとしないでください。

EDIT:ええと、私はこれに前向きでした(これは私がいつも言われていることです)が、@ Hansは、これを変更するために使用できるコンパイラスイッチがあるようだと言っています。 /EHaのドキュメントは、ここで何が起こっているかについて誤解を招くか、少なくとも不完全だと思います。誰かがこれが間違っていることを証明する決定的なドキュメントを見つけた場合、私は喜んでこの答えを削除します。

これが誤りであることが判明した場合でも、trycatchは標準であるという理由だけで使用する必要がありますが、__try__exceptはそうではありません。

17
Billy ONeal

それらは2つの非常に異なるものです。 try/catchは、おなじみのC++キーワードです。 __try/__exceptは、SEH例外をキャッチするために使用されます。 DivisionByZeroやAccessViolationなど、Windows自体によって発生する例外。 MSDNライブラリの記事 で詳しく説明されています。

Windows SEH機能を利用しているため、C++例外をキャッチするためにも使用できます。ただし、スローされた例外オブジェクトをそこから取得することはできないため、実際に例外を処理する必要がある場合は、コンテキストはありません。それは狂気です。一番のアプローチは、SEH例外をキャッチしないことです。それらは常に粗雑です。 2つを組み合わせる必要がある場合は、_set_se_translator()を使用して、SEH例外をC++例外に変換します。

44
Hans Passant

__try/__exceptは、例外をサポートしないが、構造化されたエラーコード/処理メカニズムを使用するWin32Cコードを呼び出すために設計されています。 __try/__exceptは、CエラーをC++のtry/catchと同様の例外ブロックに変換します。

詳細については、 このMSDN記事 を参照してください。

6
Randolpho

標準C++はtry/catchブロックを使用するため、標準C++ライブラリに基づく「標準」例外メカニズムが必要な場合は、これらを使用することをお勧めします。

ただし、Windows SDKで提供される構造化例外処理( ここ を参照)を使用する場合は、__try/__exceptを使用してください。

4

何かを投げると、それを捕まえる方法について多くの選択肢がなくなります。 C++例外をスローする場合(つまり、throwを使用)、try/catchを使用します。 Windowsの例外をスローする場合(つまり、RaiseExceptionを使用する場合)、__try/__exceptを使用します。それらを混ぜようとすると、あなたの人生に不必要な面倒が加わるだけです。

1
Rob Kennedy