VC ++ 9.0での例外仕様の動作を元に戻す
-
06-07-2019 - |
質問
私は、言語標準で説明されている例外仕様の動作に大きく依存している古いコードに取り組んでいます。つまり、以下で説明する形式の例外仕様違反でstd :: unexpected()を呼び出します。
foo() throw(T) { /*...*/ }
Nothrowの仕様は実際にスローしないことが保証されていますが、 throw(T)の仕様は設計の両方に違反することが予想されます。同様に、それを処理するメカニズムを提供します。
この理由は、例外処理に加えて、EHを(独自のエラークラス階層によって制御される)エラー処理メカニズムとしても使用するという設計者の決定に関係しています。 EHで提示されたイディオムは、彼らのニーズに密接にマッピングされており、彼らは最小限の努力の道を歩んだ。これは少なくとも私が見る方法であり、システムのサイズと複雑さを考えると、私には特に衝撃的ではありません。
ただし、新しい関連のない機能を含めるようになりましたが、VC ++ 9.0では、8.0で導入された例外仕様に関する標準からの逸脱により、コードが期待どおりに動作しません。 (参照: Microsoft )
標準の動作を強制する方法を探しています。コンパイラーがフォールバックを提供することを望んでいました。しかし、何もありません。
私は運が悪く、完全に開発されたエラー処理クラス階層を使用して、350,000行のコードで実行される正しく記述された標準に従ったコードを変更する必要がありますか?または、std :: unexpected()の動作を強制するのに役立つ方法を考えられますか?
編集: 背景情報を提供しています。問題のシステムは、4,000人強の生徒にサービスを提供している学校向けの学年カレンダージェネレーターです。いくつかの数字についてはまだわかりません。6学年と190のクラスに加えて、12のバーチャル(長距離教育)クラス。 MINGWは、VC ++ 8.0または9.0以外のコンパイラーと同様に問題外です。これは、この国の教育システムにサービスを提供するソフトウェアに関する規制によるものです。
コードに必要な変更は、カレンダー生成用の大幅に異なるスキーマを持つ仮想クラスの導入に対応するためのものです。そして、私はこの問題にぶつかりました。このソフトウェアは、VC ++では動作しないunexpected()マッピング(保存および復元)とbad_exceptionマッピングの両方を介してワークフローを制御する手段として、カレンダー生成プロセスのいくつかの部分で例外メカニズムを多用しています。純粋に個人的なメモでは、完全に一般的ではない場合でも、実際のメカニズムは非常にエレガントです。しかし、私は脱線します。
解決
おっしゃるように、Visual Studioには「おもしろい」機能があります。例外仕様の処理方法:
-
throw()
には通常の意味があります(関数はスローしてはなりません) - 他のすべて(例外指定なしを含む)は、
throw(...)
として解釈されます。
これを回避する方法はありません。ただし、C ++コミュニティは、例外仕様が役に立たないことにほぼ同意しています。スローされたエラータイプのランタイムチェックが本当に必要ですか?おそらく、適切な単体テストでランタイムチェックを置き換えることができます。
他のヒント
Visual C ++の例外仕様の動作は、8.0より前であっても標準に準拠している(または準拠していると主張されている)とは思わないため、アプリケーションがどのように機能しているかはわかりません。
次のような変更を実行することは可能ですか?
void f() throw(T)
{
// ...
}
to:
void f()
{
try
{
// ...
}
catch (T)
{
throw;
}
catch (...)
{
app_unexpected();
}
}