275

assert私は OpenCV のチュートリアルを研究してきましたが、この関数に出くわしました。それは何をするためのものか?

4

9 に答える 9

323

assert引数が false であることが判明した場合、プログラムを終了します (通常は assert ステートメントを引用するメッセージで)。予期しない状況が発生した場合にプログラムがより明確に失敗するようにするために、デバッグ中に一般的に使用されます。

例えば:

assert(length >= 0);  // die if length is negative.

次のように失敗した場合に表示される、より有益なメッセージを追加することもできます。

assert(length >= 0 && "Whoops, length can't possibly be negative! (didn't we just check 10 lines ago?) Tell jsmith");

または、次のようにします。

assert(("Length can't possibly be negative! Tell jsmith", length >= 0));

リリース (非デバッグ) ビルドを行っている場合、通常はコンパイラ スイッチを使用してマクロassertを定義することにより、ステートメントを評価するオーバーヘッドを取り除くこともできます。NDEBUGこれの当然の帰結は、プログラムがassert マクロの実行に依存してはならないということです。

// BAD
assert(x++);

// GOOD
assert(x);    
x++;

// Watch out! Depends on the function:
assert(foo());

// Here's a safer way:
int ret = foo();
assert(ret);

プログラムが abort() を呼び出し、何かを実行することが保証されていないという組み合わせから、アサートは、たとえば、ユーザーが文字ではなく数字を入力するのではなく、開発者が想定したことをテストするためにのみ使用する必要があります (これは、別の方法で処理されます)。

于 2009-10-15T09:51:28.627 に答える
109

assert computer ステートメントは、英語のmake sureステートメントに似ています。

于 2009-10-15T11:02:30.453 に答える
15

を見てみましょう

C++ での assert() サンプル プログラム

多くのコンパイラが assert() マクロを提供しています。assert() マクロは、パラメーターが TRUE と評価された場合に TRUE を返し、FALSE と評価された場合に何らかのアクションを実行します。多くのコンパイラは、失敗した assert() でプログラムを中止します。他の人は例外をスローします

assert() マクロの強力な機能の 1 つは、DEBUG が定義されていない場合、プリプロセッサがマクロをまったくコードにまとめないことです。これは開発中に非常に役立ち、最終製品が出荷されたときに、パフォーマンスが低下したり、プログラムの実行可能バージョンのサイズが増加したりすることはありません。

例えば

#include <stdio.h>
#include <assert.h>

void analyze (char *, int);

int main(void)
{
   char *string = "ABC";
   int length = 3;

   analyze(string, length);
   printf("The string %s is not null or empty, "
          "and has length %d \n", string, length);
}

void analyze(char *string, int length)
{
   assert(string != NULL);     /* cannot be NULL */
   assert(*string != '\0');    /* cannot be empty */
   assert(length > 0);         /* must be positive */
}

/****************  Output should be similar to  ******************
The string ABC is not null or empty, and has length 3
于 2009-10-15T09:51:27.633 に答える
8

assert() 関数は、プログラムのバグを診断できます。C では で定義され<assert.h>、C++ では で定義され<cassert>ます。その原型は

void assert(int expression);

引数の式は、変数または任意の C 式など、テストしたいものであれば何でもかまいません。expression が TRUE と評価された場合、assert() は何もしません。式が FALSE と評価された場合、assert() は stderr にエラー メッセージを表示し、プログラムの実行を中止します。

assert() をどのように使用しますか? これは、プログラムのバグ (コンパイル エラーとは異なります) を追跡するために最も頻繁に使用されます。バグはプログラムのコンパイルを妨げるものではありませんが、誤った結果をもたらしたり、不適切に実行したりする原因になります (ロックアップなど)。たとえば、あなたが書いている財務分析プログラムは、ときどき間違った答えを出すかもしれません。この問題は、変数 Interest_rate が負の値をとることによって引き起こされているのではないかと疑っていますが、これは決して起こらないはずです。これを確認するには、ステートメントを配置します

assert (interest_rate >= 0); Interest_rate が使用されるプログラム内の場所。変数が負になると、assert() マクロが警告します。その後、関連するコードを調べて、問題の原因を突き止めることができます。

assert() の動作を確認するには、次のサンプル プログラムを実行します。ゼロ以外の値を入力すると、プログラムは値を表示し、正常に終了します。ゼロを入力すると、assert() マクロはプログラムの異常終了を強制します。表示される正確なエラー メッセージはコンパイラによって異なりますが、一般的な例を次に示します。

アサーションに失敗しました: x、ファイル list19_3.c、13 行目 assert() を機能させるには、プログラムをデバッグ モードでコンパイルする必要があります。デバッグ モードを有効にする方法については、コンパイラのドキュメントを参照してください (すぐに説明します)。後でリリース モードで最終バージョンをコンパイルすると、assert() マクロは無効になります。

 int x;

 printf("\nEnter an integer value: ");
 scanf("%d", &x);

 assert(x >= 0);

 printf("You entered %d.\n", x);
 return(0);

整数値を入力してください: 10

10 を入力しました。

整数値を入力してください: -1

エラー メッセージ: プログラムの異常終了

システムとコンパイラによってエラー メッセージが異なる場合がありますが、一般的な考え方は同じです。

于 2014-01-12T04:21:29.547 に答える
4

「例外を発生させる」や「実行を停止する」などは、ほとんどのコンパイラに当てはまりますが、すべてではありません。(ところで、実際に例外をスローする assert ステートメントはありますか?)

これは、c6x や他の TI コンパイラで使用される assert の興味深い、わずかに異なる意味です。これらのコンパイラは、特定の assert ステートメントを確認すると、そのステートメントの情報を使用して特定の最適化を実行します。邪悪。

C での例:

int dot_product(short *x, short *y, short z)
{
  int sum = 0
  int i;

  assert( ( (int)(x) & 0x3 ) == 0 );
  assert( ( (int)(y) & 0x3 ) == 0 );

  for( i = 0 ; i < z ; ++i )
    sum += x[ i ] * y[ i ];
  return sum;
}

これにより、配列が 32 ビット境界で整列されていることがコンパイラに通知されるため、コンパイラはその種類の整列用に作成された特定の命令を生成できます。

于 2009-10-15T10:29:39.663 に答える
0

評価した値が偽の場合にプログラムの実行を停止する機能です。通常、リリース設定でコンパイルしたときに結果のバイナリにコンパイルされないように、マクロで囲まれています。

これは、作成した仮定をテストするために使用するように設計されています。例えば:

void strcpy(char* dest, char* src){
    //pointers shouldn't be null
    assert(dest!=null);
    assert(src!=null);

    //copy string
    while(*dest++ = *src++);
}

あなたが望む理想は、無効な引数で関数を呼び出すなど、プログラムでエラーを発生させることができ、セグメンテーション違反 (または期待どおりに動作しない) の前にアサートをヒットできることです。

于 2009-10-15T09:55:34.573 に答える