48

すべての C++ 開発者が知っておくべき構造化例外に関する重要なポイントは何ですか?

4

5 に答える 5

46

これらは Unix シグナルに相当する Win32 であり、アクセス違反、不正な命令、ゼロ除算などの CPU 例外をキャッチできます。

適切なコンパイラ オプション (Visual C++ の場合は /EHa) を使用すると、C++ 例外は、スタックの巻き戻しが C++ (ユーザー) 例外と SEH (OS) 例外の両方に対して適切に機能するのと同じメカニズムを使用します。

C++ 例外とは異なり、SEH は型付けされませんが、例外コード (原因) と、エラーが発生したコードとエラー時に CPU レジスタが保持していたものに関する追加情報を持つ同じデータ構造をすべて共有します。詳細についてはGetExceptionCode、 およびGetExceptionInformationを参照してください。

また、SEH には「最初のチャンス」処理があり、巻き戻しによってすべてのローカル変数が破棄される前に、例外をログに記録するか、別の方法で処理することができます。

于 2010-05-06T17:09:06.337 に答える
37

私は最近、SEHによって間接的に引き起こされた問題を抱えていました。特に、すべての開発者が知っておくべきSEHの1つの機能が原因です。

SEHを使用すると、デストラクタは呼び出されないため、デストラクタにクリーンアップコードがある場合、デストラクタはクリーンアップされません。

私たちの問題は、コンストラクターにLockがあり、デストラクタにUnlockがあるオブジェクトによってラップされたクリティカルセクションが原因で発生しました。

デッドロック状態にあり、その理由を理解できませんでした。コードとダンプを調べてデバッグしてから約1週間後、COMによって処理され、クリティカルセクションがロックされたままになる例外があったためであることがようやくわかりました。 。プロジェクトプロパティのVSのコンパイルフラグを変更して、SEHに対してもデストラクタを実行するように指示し、問題を解決しました。

したがって、コードでSEHを使用していない場合でも、(COMのように)使用していて予期しない動作を引き起こす可能性のあるライブラリを使用している可能性があります。

于 2010-10-15T12:28:22.417 に答える
25

それらは標準 C++ の一部ではないことを知っておく必要があります。これらは Microsoft の発明であり、C++ 以外の言語で使用できます。

于 2010-05-06T17:08:12.720 に答える
24

Win32™ 構造化例外処理の深みに関する短期集中コース

その記事は SEH を使いこなすためのリファレンスです。13年経った今でも最高です。

SEH vs. C++ Exception Handling Differencesについては、MSDN に専用のトピックがあります。

SEH が議論されている場合、C++ 開発者が知っておくべきいくつかのこと:

C/C++ SEH例外ハンドラの記述:

__try 
{
   // guarded code
}
__except ( expression )
{
   // exception handler code
}

これはC++ の例外処理ではなく、ストレート inot SEH をフックするための MS 固有の拡張機能です。これは、ありふれた C++ 例外とは大きく異なります。これらを使用するには、SEH を十分に理解している必要があります。

C/C++ SEH終了ハンドラの記述:

__try {
   // guarded code
}
__finally {
   // termination code
}

SEH ハンドラーと同様に、これを C++ 例外セマンティクスと混同しないでください。SEH について十分に理解している必要があります。

_set_se_translator: これは、非同期例外が使用されている場合に、SEH 例外を C++ タイプの例外に変換する関数です/EHa .

そして最後に、個人的な意見: C++ 開発者は SEH を知っているべきですか? 初めての新人.ecxrを実行した後は、C++ の例外を押し付けるようになったとき、便宜上提供された錯覚に過ぎないことを理解できます。起こっているのはSEHだけです。

于 2010-05-06T21:22:09.327 に答える
1

重要な点は、SEH をいつ使用し、いつ標準 C++ 例外を使用するかを知ることです。まず、システムを 1 つだけ選択します。ミキシング システムは問題が発生する傾向があり、適切に実装するには両方を深く理解する必要があります。次に、高レベルでは、SEH は C++ に限定されませんが、標準の C++ 例外は Windows に限定されません。これが決定に影響しない場合は、不適切でない限り、標準の例外を選択してください (SEH でできることの詳細については、他の回答を参照してください)。

Microsoft のドキュメント(2018 年 8 月 13 日付け)からの引用は、この結論を裏付けています。

構造化例外処理 (SEH) は、ハードウェア障害などの特定の例外的なコード状況を適切に処理するための C に対する Microsoft 拡張機能です。Windows と Microsoft C++ は SEH をサポートしていますが、コードの移植性と柔軟性が向上するため、ISO 標準の C++ 例外処理を使用することをお勧めします。それでも、既存のコードを維持したり、特定の種類のプログラムを処理したりするために、SEH を使用しなければならない場合があります。

拡張機能の作成者が、ほとんどの場合、拡張機能を使用しないことを推奨するのはなぜですか? おそらく、拡張機能が C 用に作成されており、現在のコンテキストが C++ であるためです。言語は似ているので、「特定の種類のプログラム」だけが真に恩恵を受けるとしても、副次的利益として SEH を C++ に移植することはおそらく十分に簡単でした。(または、他の理由かもしれません。C++ が標準化される前に移植が開始された可能性があります。歴史は複雑になります。)

于 2019-06-14T15:51:59.863 に答える