static_assert
がコンパイル時にアサーションを作成し、assert
-実行時にアサーションを作成することは知っていますが、実際の違いは何ですか?私が理解している限り、これらのコードは次のようなコードです。
if (condition == false) exit();
static_assert
が機能する場所、またはonlyassert
の例を誰かに教えてもらえますか?if
ステートメントでは実行できないことは何ですか?あなたは3つの質問をするので、私はそれらのそれぞれに答えようとします。
static_assert
が機能する場所、またはonlyassert
の例を誰かに教えてもらえますか?static_assert
は、コンパイル時にコード内のロジックをテストするのに適しています。 assert
は、実行時に常に1つの結果が得られるはずであるケースをチェックするのに適していますが、予期しない状況で何らかの理由で予期しない結果が生じる可能性があります。たとえば、メソッドに渡されたポインタがassert
であるかどうかを判断するためにnull
を使用する必要があるのは、そのようなことが発生しないように思われる場合のみです。 static_assert
はそれをキャッチしません。
if
ステートメントでは実行できないことをしていますか?assert
はプログラムの実行を中断するために使用できるため、適切なエラーメッセージであるif
を使用し、プログラムの実行を停止して同様の効果を得ることができますが、assert
はその場合は少し簡単です。 static_assert
はもちろんコンパイル問題の検出にのみ有効ですが、if
はプログラムで有効でなければならず、コンパイル時に同じ期待値を評価することはできません。 (ただし、if
を使用すると、実行時にエラーメッセージを出力できます。)
どういたしまして!
static_assert
はcompilationを指定されたメッセージで失敗させることを目的としていますが、従来のassert
はプログラムの実行を終了することを目的としています。
かしこまりました。
静的条件に違反した場合にコンパイルを失敗させたい場合は、_static_assert
_のみが機能します:static_assert(sizeof(void*) != 3, "Wrong machine Word size");
*動的アサーションのみが動的条件をキャッチできます:assert(argc == 1);
単純なif
ステートメントは、有効でコンパイル可能でなければなりません。静的アサーションはコンパイルの失敗を引き起こします。
番号。
*)実用的な例は、int x; std::move<int&&>(x)
などの一般的なテンプレート構造の乱用を防ぐことです。
それらを使用することは悪い習慣ですか?
乱用された場合、はい、特にassert
。
1つの乱用は、アクティブなassert
ステートメントに依存しています。 assert
を定義してコンパイルすると、NDEBUG
は何もしないため、assert
に依存して何かを行うことはできません。多くの場合、量産コードはNDEBUG
が定義された状態でコンパイルされ、これらのassert
ステートメントが確実に消えるようにします。
1〜2日以上存続しない1回限りのプログラムを作成しているのでない限り、ユーザー入力の検証に使用すべきではありません。ユーザーはコードがどこで失敗したかを気にせず、出力されるメッセージは多くのユーザーにとって外国語のように見えます。エラーの修正方法はユーザーに通知されません。また、設計上、非常に許容範囲が広くなっています。ユーザー入力エラーへの応答として発行されるメッセージは、問題を修正する方法をユーザーに通知するメッセージである必要があります。メッセージの後の最善のアクションは、ユーザーにエラーを修正する方法を提供することです。それができない場合、そして実行可能な唯一の応答がプログラムを終了することである場合、プログラムは完全に終了するはずです。設計上、assert
は正常にシャットダウンされません。 abort()
ではなくexit()
を呼び出します。
多くのマシンでabort()
を使用すると、コアダンプが生成されます。コアダンプは、プログラマにとって素晴らしいエラーメッセージです。コアダンプを使用すると、プログラマーはデバッガーを使用して、問題の原因を詳細に確認できます。 abort()
の欠点は、物事がクリーンアップされないことです。中止すると、「自動または静的ストレージ期間のオブジェクトのデストラクタを実行せず、atexit()
に渡された関数を呼び出さずにプログラムを終了します。」
結論:assert
を使用してプログラミングエラーをテストすることは問題ありませんが、本番環境以外の設定でのみ可能です。他のものを使用して、ユーザーエラーをテストします。
static_assert
はコンパイラ指令です。コンパイル時に型情報を確認できます。コンパイルが失敗し、ほとんどのIDEでキャッチされ、IDEのエラーウィンドウに表示されるエラーメッセージが生成されます。
static_assert(sizeof(int) == 4,"int should be 4 bytes");
assert
はランタイム用で、変数の値を確認できます。アサーションが失敗すると、アサーションがトリガーされます。これにより、一部のオペレーティングシステムでは実行時に表示されるエラーメッセージボックスが表示されます(実装に依存するアサート)。
assert(("mypointer should never be null!", mypointer != nullptr));