0

デバッグ中にアサーションを使用する例:

char* append(char* pStr, const char* pAddStr)
{
    // Verify non-null pointers

    assert(pStr != nullptr);
    assert(pAddStr != nullptr);

    // Code to append pAddStr to pStr...
}

単純なプログラムで null ポインター引数を指定して append() 関数を呼び出すと、マシンで次の診断メッセージが生成されました。

Assertion failed: pStr != nullptr, file c:\beginning visual c++ 2010\examples visual studio project files\tryassertion\tryassertion\tryassertion.cpp, line 10

アサーションが必要かどうか知りたいです。if-else 式を使用して独自のエラー メッセージを出力できる場合、それらを使用する意味は何ですか?

4

3 に答える 3

4

アサーション条件付きチェックです。これは、次のような(簡略化された)単なるマクロです。

#define assert(b) if (!(b)) { std::cerr << ...; exit(1); }

私は2つの利点を考えることができます:

  1. リリース モード (つまり、デバッグ モードではない) でコンパイルすると、すべてのasserts は何もコンパイルされないため、実行時のオーバーヘッドは発生しません。
  2. assertイディオムです。他のプログラマーはそれらを探すことを知っており、それらは「通常の」制御フローとも異なります。
于 2011-12-11T18:22:39.750 に答える
1

アサーションは、特定の基本的な仮定が満たされていることを確認するために使用されます。基本的に、「起こり得ない」すべての場合にアサーションを設定します。最も一般的には、APIの使用方法をアサーションします。たとえば、前提条件と事後条件(append関数の正しい使用法をチェックするアサーションを含む例のように)。実行時に発生することがわかっていて、事前に防ぐことができないその他のエラー(たとえば、ファイルが見つからない、または許可が不十分な種類のエラー)については、エラー処理コードを作成する必要があります。

アサーションはリリースコンパイルに含まれていないため、デバッグモードのテスト実行ですでに発生している重大なプログラミングエラーをキャッチするためにのみ使用できます。

于 2011-12-11T18:26:00.453 に答える
1

アサーションに違反する唯一のケースがプログラム ロジックのエラーである場合は、アサーションを使用する必要があります。入力または外部の可能な条件 (つまり、ファイルが見つからない) が原因で実際​​に発生する可能性があることに対しては、通常の条件を使用しifます。thenelse

プログラム ロジックに問題があることが確実にわかっている場合、実行を継続しようとしてもあまり意味がありません...プログラムは、あなたが考えているものとは異なる動作をしています (そうでなければアサーションがトリガーされないため)。オプションは、問題が何であるかを叫んですぐに死ぬことです。

多くの場合、コードが「リリース」モードでコンパイルされるとアサーションが削除されますが、プログラム ロジックが非常に複雑であり、実行を継続して悪い出力を生成すると実行を停止するよりも大きな問題が発生する場合は、アサーションをそのままにしておくことが理にかなっている場合があります。

初心者のプログラマーがアサーションで陥る「トラップ」は、アサーション コードがリリース モードで削除されると、アサーション内の式が評価されなくなることです。したがって、プログラムがその式の副作用に依存している場合は、 'トラブルになるだろう...例えば:

...
assert(insert_record(db, data) == DB_OK);  // <== this is bad
...

アサーションが離れて定義されている場合、挿入はまったく行われず、リリースモードでは機能せず、問題をデバッグしようとすると代わりに機能するプログラムが残ります。

于 2011-12-11T18:37:28.630 に答える