私はOpenCVチュートリアルを研究していて、そのassert
機能に出くわしました。それは何をするためのものか?
私はOpenCVチュートリアルを研究していて、そのassert
機能に出くわしました。それは何をするためのものか?
回答:
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()を呼び出すプログラムと何もしないことが保証されていない組み合わせから、ユーザーが文字ではなく数値を入力するのではなく(たとえば、他の方法で処理されます)。
assert
通常は例外が発生します」-C ++では、「例外」は発生しませんが、アボートを呼び出します...少し異なります。
#
文字はコメントを導入しません。
assert("error message", expression)
アサートコンピュータ文は、文と類似していることを確認してください英語インチ
を見てみましょう
多くのコンパイラーは、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
assert()関数はプログラムのバグを診断できます。Cではで定義され<assert.h>
、C ++ではで定義され<cassert>
ます。そのプロトタイプは
void assert(int expression);
引数式は、テストしたい任意のもの(変数または任意のC式)にすることができます。式が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
エラーメッセージ:プログラムの異常終了
エラーメッセージは、システムとコンパイラによって異なりますが、一般的な考え方は同じです。
「例外を発生させる」や「実行を停止する」などのことは、ほとんどのコンパイラでは当てはまるかもしれませんが、すべてでは当てはまりません。(ところで、本当に例外をスローするassertステートメントはありますか?)
これは、c6xと他のTIコンパイラが使用するアサートの興味深い、わずかに異なる意味です。特定のアサートステートメントを確認すると、これらのコンパイラはそのステートメントの情報を使用して特定の最適化を実行します。邪悪な。
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ビット境界で整列されていることをコンパイラーに伝えます。そのため、コンパイラーは、そのような整列のために作成された特定の命令を生成できます。
C ++ 11 N3337標準ドラフト
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf
19.3アサーション
1(表42)で説明されているヘッダー<cassert>は、C ++プログラムのアサーションを文書化するマクロと、アサーションチェックを無効にするメカニズムを提供します。
2内容は、標準Cライブラリヘッダー<assert.h>と同じです。
C99 N1256標準ドラフト
http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf
7.2診断<assert.h>
1ヘッダー
<assert.h>
はアサートマクロをNDEBUG
定義し、で定義されていない別のマクロを参照してい<assert.h>
ます。NDEBUG
<assert.h>がインクルードされているソースファイルのポイントでマクロ名として定義されている場合、assertマクロは次のように定義されます。#define assert(ignore) ((void)0)
アサートマクロは、NDEBUG
<assert.h>
が含まれるたびに、NDEBUGの現在の状態に従って再定義さ れます。2. assertマクロは、実際の関数としてではなく、マクロとして実装されます。実際の関数にアクセスするためにマクロ定義が抑制されている場合、動作は未定義です。
7.2.1プログラム診断
7.2.1.1アサートマクロ
あらすじ
1。
#include <assert.h> void assert(scalar expression);
説明
2 assertマクロは診断テストをプログラムに入れます。void式に展開されます。これが実行されると、式(スカラー型を持つ必要があります)がfalse(つまり、0に等しい)の場合、assertマクロは失敗した特定の呼び出しに関する情報(引数のテキスト、後者は、それぞれ前処理マクロの値である-ソースファイル、ソース行番号、及び封入機能の名前
__FILE__
及び__LINE__
識別子の__func__
実装で定義されたフォーマットで標準エラーストリームに)。165)次に、アボート関数を呼び出します。戻り値
3 assertマクロは値を返しません。
else ifとprintfが通常よりもassert()関数を使用する主な理由は3つあります。
assert()関数は主にデバッグ段階で使用されますが、最終的なコードでうまく行かない可能性がある条件をテストするたびに、printfステートメントを使用して書き込むのは面倒です。
大規模なソフトウェア展開では、assertが非常に便利です。assert()関数のヘッダーファイルをリンクする前に定義されたNDEBUGマクロを使用して、コンパイラーにassert文を無視させることができます。
assert()は、関数またはコードを設計していて、コードが機能して何が機能しないのかを知りたい場合や、基本的に仮定で遊んでいると評価するためのif elseを最後に含めたい場合に便利です。
評価した値が偽の場合、プログラムの実行を停止する関数です。通常、マクロで囲まれているため、リリース設定でコンパイルした場合、結果のバイナリにコンパイルされません。
それはあなたがした仮定をテストするために使用するように設計されています。例えば:
void strcpy(char* dest, char* src){
//pointers shouldn't be null
assert(dest!=null);
assert(src!=null);
//copy string
while(*dest++ = *src++);
}
必要な理想は、無効な引数を使用して関数を呼び出すなど、プログラムでエラーを発生させ、segfaultする前にアサートをヒットする(または期待どおりに機能しない)ことです。
さらに、これを使用して、動的割り当てが成功したかどうかを確認できます。
コード例:
int ** p;
p = new int * [5]; // Dynamic array (size 5) of pointers to int
for (int i = 0; i < 5; ++i) {
p[i] = new int[3]; // Each i(ptr) is now pointing to a dynamic
// array (size 3) of actual int values
}
assert (p); // Check the dynamic allocation.
に似ている:
if (p == NULL) {
cout << "dynamic allocation failed" << endl;
exit(1);
}
new
あなたが指定しない限り、割り当ての失敗の例外がスローされますnothrow
(あなたがここでありませんでした)。さらに、あなたのフォーマットは奇妙でexit
悪です。
assert()
、決して、決して、決して、発生してはならないことをデバッグしてスタンプするためのものです。