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