私はずっと assert は単なるエラー報告関数だと思っていましたが、実際にはなんとマクロであり、その役割は「エラー報告」ではないのです。
ある程度理解を深めた後、assert() の使い方は一種の「契約プログラミング」のようなものであることに気づきました。私の理解では、それはプログラムが私の仮定の条件下で正常かつ良好に動作することを表しており、実際には if 文に相当します:
if(假设成立)
{
程序正常运行;
}
else
{
报错&&终止程序!(避免由程序运行引起更大的错误)
}
しかしこのように書くと無数の if 文ができてしまい、1つの if 文の括弧がファイルの先頭から末尾まで及ぶことさえあります。しかもほとんどの場合、検証したい仮定は単なる偶発的な事象に過ぎず、あるいは単にいくつかの最悪のケースが発生するかどうかをテストしたいだけです。そこで assert() があります。
assert マクロのプロトタイプは assert.h 内で定義されており、その役割は、条件がエラーを返した場合にプログラムの実行を終了することです。
#include "assert.h" void assert( int expression );
assert の役割は、まず式 expression を評価し、その値が偽(すなわち0)である場合、まず stderr にエラーメッセージを出力し、その後 abort を呼び出してプログラムの実行を終了することです。
assert を使用する欠点は、頻繁に呼び出すとプログラムのパフォーマンスに大きな影響を与え、余分なオーバーヘッドが増えることです。
デバッグ終了後には、#include を含む文の前に #define NDEBUG を挿入することで assert の呼び出しを無効にできます。サンプルコードは次のとおりです:
#include #define NDEBUG #include
使い方のまとめと注意事項
1) 関数の先頭で渡された引数の正当性を検証する
例:
int resetBufferSize(int nNewSize)
{
//功能:改变缓冲区大小,
//参数:nNewSize 缓冲区新长度
//返回值:缓冲区当前长度
//说明:保持原信息内容不变 nNewSize<=0表示清除缓冲区
assert(nNewSize >= 0);
assert(nNewSize <= MAX_BUFFER_SIZE);
...
}
2) 各 assert は1つの条件のみを検証すること。複数の条件を同時に検証すると、アサーションが失敗した場合にどの条件が失敗したのか直感的に判断できないため。
悪い例:
assert(nOffset>=0 && nOffset+nSize<=m_nInfomationSize);
良い例:
assert(nOffset >= 0); assert(nOffset+nSize <= m_nInfomationSize);
3) 環境を変更する文は使用できない。assert は DEBUG でのみ有効なので、これを行うとプログラムが実際に実行される際に問題が発生する。
誤り: assert(i++ < 100)
これは、もしエラーが発生した場合、例えば実行前に i=100 であれば、この文は実行されず、その結果 i++ というコマンドも実行されないからです。
正しい例:
assert(i < 100) i++;
4) assert と後続の文は1行空けて、論理・視覚のな統一感を持たせること。
5) 場所によっては、assert は条件フィルタリングの代わりにはならない。
プログラムは通常、Debug バージョンと Release バージョンに分けられます。Debug バージョンは内部デバッグ用で、Release バージョンはユーザーに配布するためのものです。アサーション assert は Debug バージョンでのみ有効なマクロであり、「あってはならない」状況をチェックするために使用されます。以下はメモリコピーのプログラムです。実行中に assert のパラメータが偽になると、プログラムは中断されます(通常は、どこで assert が発生したかを示すダイアログが表示されます)。
以下はアサーションを使用する際のいくつかの原則です:
- (1)アサーションを使用して、発生すべきではない不正な状況を捉えます。不正な状況とエラー状況を混同してはなりません。後者は必然的に存在し、必ず処理しなければならないものです。
- (2)アサーションを使用して関数のパラメータを検証する。
- (3)関数を作成する際には、繰り返し検討し、「どのような仮定を置こうとしているのか?」と自問すること。仮定が確定したら、アサーションを使用してその仮定をチェックする。
- (4)一般的な教科書では、プログラマに防衛的プログラミングを行うよう勧めていますが、このプログラミングスタイルはエラーを隠してしまうことを覚えておいてください。防衛的プログラミングを行う際、「あり得ない」ことが実際に発生した場合には、アサーションを使用して警告を発してください。
ASSERT () はデバッグ時によく使われるマクロです。プログラム実行時に括弧内の式を評価し、式が FALSE (0) の場合、プログラムはエラーを報告して実行を終了します。式が0でない場合は、後続の文の実行を続けます。このマクロは通常、プログラム内に明らかに不正なデータが出現したかどうかを判定するために使われます。もし出現した場合、プログラムを終了して重大な結果を防ぎ、同時にエラーの発見を容易にします。
ASSERT は Debug バージョンでのみ有効です。Release バージョンとしてコンパイルすると無視されます。
原文のアドレス:https://www.cnblogs.com/thisway/p/5558914.html