リリース ビルドのパフォーマンスに影響を与えずにデバッグを容易にするために、C++ コードに多くのアサーションを追加する傾向があります。Nowassert
は、C++ メカニズムを考慮せずに設計された純粋な C マクロです。
一方、C++ は を定義しますstd::logic_error
。これは、プログラムのロジックにエラーがある場合にスローされることを意図しています (名前の由来)。インスタンスをスローすることは、完全で、より C++ っぽいassert
.
問題はassert
、abort
両方ともデストラクタを呼び出さずにすぐにプログラムを終了するため、クリーンアップをスキップすることですが、手動で例外をスローすると不要なランタイム コストが追加されます。これを回避する 1 つの方法は、独自のアサーション マクロを作成することです。このマクロSAFE_ASSERT
は C 版と同じように機能しますが、失敗すると例外がスローされます。
この問題については、次の 3 つの意見を考えることができます。
- C のアサートに固執します。プログラムはすぐに終了するため、変更が正しく展開されているかどうかは問題ではありません。また、
#define
C++ で s を使用するのも同様に悪いことです。 - 例外をスローし、 main() でキャッチします。コードがプログラムのどの状態でもデストラクタをスキップできるようにすることは悪い習慣であり、絶対に避ける必要があり、terminate() の呼び出しも同様です。例外がスローされた場合は、キャッチする必要があります。
- 例外をスローして、プログラムを終了させます。 プログラムを終了させる例外は問題あり
NDEBUG
ません。これは、リリース ビルドでは決して発生しません。キャッチは不要で、内部コードの実装の詳細を に公開しmain()
ます。
この問題に対する決定的な答えはありますか? 専門的な参考文献はありますか?
編集済み:デストラクタをスキップすることは、もちろん、未定義の動作ではありません。