15

c++でアサーションはどのように行われますか? サンプルコードは大歓迎です。

4

8 に答える 8

35

アサートは、コードが行う仮定を明示的にチェックする方法であり、考えられる問題を絞り込むことで多くのバグを追跡するのに役立ちます。これらは通常、アプリケーションの特別な「デバッグ」ビルドでのみ評価されるため、最終リリース バージョンの速度が低下することはありません。

ポインタを引数として取る関数を書いたとしましょう。あなたのコードがポインタが非 NULL であると仮定する可能性は十分にあります。方法は次のとおりです。

#include <assert.h>

void function(int* pointer_arg)
{
    assert(pointer_arg != NULL);

    ...
}

注意すべき重要なことは、リリース ビルドには存在しないため、アサートする式に副作用があってはならないということです。したがって、次のようなことは絶対にしないでください。

assert(a++ == 5);

アサーションに意味を持たせるために、アサーションに小さなメッセージを追加することを好む人もいます。文字列は常に true に評価されるため、次のように記述できます。

assert((a == 5) && "a has the wrong value!!");
于 2008-10-31T11:34:30.013 に答える
6

アサーションはブール式であり、通常は常に真である必要があります。

それらは、期待したことも起こることを保証するために使用されます。

void some_function(int age)
{
     assert(age > 0);
}

年齢を処理する関数を作成しました。また、常に適切な引数を渡していることを「知っている」ので、アサートを使用します。それは、「これは絶対にうまくいかないことはわかっているが、もしそうなら知りたい」と言っているようなものです。

したがって、賢明なユーザー入力をチェックすることではありません。何かがうまくいかないシナリオがある場合は、アサートを使用しないでください。実際のチェックを行い、エラーに対処してください。

通常、アサートはデバッグ ビルド専用であるため、アサートに副作用のあるコードを配置しないでください。

于 2008-10-31T11:33:25.103 に答える
5

アサーションは、通常、入力パラメーターと戻り結果に関して、設計の仮定を検証するために使用されます。例えば

// Given customer and product details for a sale, generate an invoice

Invoice ProcessOrder(Customer Cust,Product Prod)
{
  assert(IsValid(Cust));
  assert(IsValid(Prod);
'
'
'
  assert(IsValid(RetInvoice))
   return(RetInvoice);

}

assert ステートメントは、コードの実行に必須ではありませんが、入力と出力の有効性をチェックします。入力が無効な場合、呼び出し関数にバグがあります。入力が有効で出力が無効な場合、このコードにはバグがあります。この assert の使用の詳細については、design by contractを参照してください。

編集: 他の投稿で指摘されているように、assert の既定の実装はリリース ランタイムに含まれていません。私を含む多くの人が使用する一般的な方法は、リリース ビルドに含まれているが診断モードでのみ呼び出されるバージョンに置き換えることです。これにより、完全なアサーション チェックを使用して、リリース ビルドでの適切な回帰テストが可能になります。私のバージョンは次のとおりです。

extern  void _my_assert(void *, void *, unsigned);

#define myassert(exp)                               \
{                                                   \
    if (InDiagnostics)                              \
        if ( !(exp) )                               \
            _my_assert(#exp, __FILE__, __LINE__);   \
}                                                   \

この手法には実行時のオーバーヘッドがわずかにありますが、フィールドに持ち込まれたバグを追跡するのがはるかに簡単になります。

于 2008-10-31T11:38:01.193 に答える
3

アサーションを使用して、「あり得ない」状況をチェックします。

典型的な使用法: 関数の先頭にある無効/不可能な引数をチェックします。

めったに見られませんが、それでも有用です: ループの不変条件と事後条件。

于 2008-10-31T12:07:52.953 に答える
2

アサーションは、プログラムに含まれる可能性のある仮定をテストできるステートメントです。これは、プログラム ロジック (前提条件と事後条件) を文書化するのに特に役立ちます。通常、失敗したアサーションは実行時エラーをスローします。これは、プログラムに何か非常に問題があることを示しています。真であると想定していたものがそうではなかったため、アサーションが失敗しました。通常の理由は次のとおりです。関数のロジックに欠陥があるか、関数の呼び出し元が不正なデータを渡しました。

于 2008-10-31T11:34:59.437 に答える
1

アサーションは、条件が満たされた場合にプログラムを即座に停止させ、エラー メッセージを表示させるプログラムに追加するものです。通常、コード内で決して発生しないと思われることに対して使用します。

于 2008-10-31T11:34:21.280 に答える
1

これは、初期の C 時代から私たちにもたらされたアサート機能には対応していませんが、プロジェクトで Boost を使用できる場合は、 Boost StaticAssert機能にも注意する必要があります。

標準の C/C++ アサートは実行時に機能します。Boost StaticAssert 機能を使用すると、コンパイル時にいくつかのクラスのアサーションを作成して、論理エラーなどをより早期にキャッチできます。

于 2008-10-31T16:24:04.140 に答える
0

アサーションの定義とサンプル コードを次に示します。簡単に言うと、アサーションとは、開発者が任意の時点でのコードの状態に関する自分 (または彼女) の仮定をテストする方法です。たとえば、次のコードを実行していたとします。

mypointer->myfunct();

おそらく、mypointer が NULL ではないことを主張したいでしょう。それは、呼び出しの前に mypointer が NULL になることは決してないと仮定しているからです。

于 2008-10-31T11:34:46.847 に答える