私は Windows プログラマーではありませんが、構造化された例外処理を使用してハードウェア例外をソフトウェア例外のように扱うことは、次のことを意味しているように思えます。
- あなたのコードは、C++ 標準で未定義または実装定義の動作 (ゼロ除算など) を生成することを行います。
- Windows では、SEH を有効にすると、その場合に例外がスローされると定義されています。
- この事実を使用して、例外をキャッチしたり、終了ハンドラーを実行したりします。
したがって、IMOに尋ねる質問は次のとおりです。
- あなたのプログラミング タスクは、標準の C++ では処理できない性質のものですか? (または、ハードウェア例外を許可することによって得られるものよりもかなり劣る方法でのみ処理できます)。
- コードが非標準になったときに、本当に対策を講じる必要がありますか?
- そもそもハードウェア例外を引き起こさないようにコードを書くことができますか?
答えが「はい」、「はい」、「いいえ」の場合、構造化例外処理が必要です。それ以外の場合は、回避できる可能性があります。その場合は、回避したいでしょう。例外セーフなコードを書くのは難しいので、提供できる例外保証が強力であればあるほど、より良い結果が得られます。SEH でゼロ除算する可能性のあるコードは、nothrow の保証を提供していません。おそらく、呼び出し元がダフ データを与えないように少し再設計することで、そうすることができます。ただし、関数が他の理由で既に例外をスローする必要がある場合は、ハードウェア トラップのために例外をスローしても、事態は悪化しない可能性があります。
注目すべき特殊なケースの 1 つは、メモリ割り当てです。.NET がこれを行うかどうかはわかりませんが、Linux では、割り当てに十分な仮想アドレス空間がない場合にのみ割り当てが失敗します。物理メモリは最初の使用時にコミットされ、十分でない場合はハードウェア例外が発生します。メモリ割り当ては失敗時に std::bad_alloc をスローすると想定されており、実装は標準のこの要件の実装に失敗するため、場合によっては、ハードウェア例外をソフトウェアに変換することが正しいことです。ただし、そのハードウェア例外は予期しない場所で発生する可能性があるため (スローされないと思われるルーチンを含む)、適切に処理することはまだ不可能な場合があります。これが、スローの代わりに Linux コア ダンプが発生する理由です。実際には、完全に初期化されたものはすべてそのコンストラクターをクラッシュさせます。これは多くの場合、ソフトウェア例外が代わりに役立つ割り当てに十分近いものです。