本当にassertを使うの?
3079 ワード
このブログを書くのはlighttpdソースコードを読むことでassertアプリケーションに関する疑問に直面したからです.
Lighttpdのソースコードを読むと、mallocの呼び出し結果をassertチェックします.例えば、Buffer.c:
ここのassert(b)に問題があるようですが、実際にreleaseバージョンが実行中にmallocがNULLを返すことはありませんか?その後、《Writing Solid Code 》の本を読んで答えを見つけた.
assertの基本的な使い方はもう疲れませんが、assertの実際の応用であるRecommended practiceをまとめてみましょう.
1、断言で関数パラメータを確認する
主に次のような状況があります.ポインタはNULLの断言ではありません. index値またはsize値が負または既知の限界値未満の断言ではない.この1つは、プログラムから無定義の特性を削除するか、プログラムで断言を使用して無定義の特性の不正使用を検出する についても説明することができる.
2、各アサーションは、ヘッダファイルの関数機能記述のアサーション部分で説明しなければならない(他人の時間を無駄にしないでください.-詳細な説明がはっきりしないアサーション).例えば、次のようにします.
断言がなければ「Nothing」と書きます.
3、断言とエラーチェックの違い
断言を正しく使用するには、プログラムエラー(program errors)とランタイムエラー(run-time errors)の違いを明確にしなければならない.プログラムエラーはバグであり、永遠に発生するべきではありません. 実行時エラーは、プログラムの実行時に発生する可能性がある.
断言はランタイムエラーを処理するメカニズムではありません.例えば正の数を入力する必要がある場合,ユーザは負の数を入力し,断言で検出すればよい設計ではない.この場合,適切なエラーチェックとリカバリ処理のコードで処理する必要がある.
ライトtpdに戻ってmalloc関数の戻り値をassertで断言するのも、プログラムエラーではなく実行時エラーだと思います.だから、『Cとポインタ』という本ではmallocに対してNULLを返す処理は、エラーチェックディスペンサで処理されていると思います.
4、断言とバグ
断言は大きく分けて前置条件(Preconditions)、後置条件(Postconditions)、不変性条件(Invariants)
前置条件が成立せず、Assertion violationsが発生した場合、この関数を呼び出すコードにバグが存在し、できるだけ早く見つけて解決する必要がある.
後置条件が成立せず、Assertion violationsが発生した場合、(関数の)実装コードにバグがあり、できるだけ早く見つけて解決する必要がある.
例:
このコードは、この関数の呼び出しがパラメータ0に入ることが不可能であることを示し、この場合、この関数を呼び出すコードにバグがあることを示す.
以上は自分の少しの理解で、达人の指摘を歓迎します!!!参照:How to use assertions in C
《 Writing Solid Code 》
Lighttpdのソースコードを読むと、mallocの呼び出し結果をassertチェックします.例えば、Buffer.c:
buffer* buffer_init(void) {
buffer *b;
b = malloc(sizeof(*b));
assert(b);
b->ptr = NULL;
b->size = 0;
b->used = 0;
return b;
}
ここのassert(b)に問題があるようですが、実際にreleaseバージョンが実行中にmallocがNULLを返すことはありませんか?その後、《Writing Solid Code 》の本を読んで答えを見つけた.
assertの基本的な使い方はもう疲れませんが、assertの実際の応用であるRecommended practiceをまとめてみましょう.
1、断言で関数パラメータを確認する
主に次のような状況があります.
2、各アサーションは、ヘッダファイルの関数機能記述のアサーション部分で説明しなければならない(他人の時間を無駄にしないでください.-詳細な説明がはっきりしないアサーション).例えば、次のようにします.
* Asserts:
* 'size' is no greater then LIMIT.
* 'format' is not NULL.
* The function result is no greater than LIMIT.
*/
断言がなければ「Nothing」と書きます.
* Asserts:
* Nothing
*/
( , , )
3、断言とエラーチェックの違い
断言を正しく使用するには、プログラムエラー(program errors)とランタイムエラー(run-time errors)の違いを明確にしなければならない.
断言はランタイムエラーを処理するメカニズムではありません.例えば正の数を入力する必要がある場合,ユーザは負の数を入力し,断言で検出すればよい設計ではない.この場合,適切なエラーチェックとリカバリ処理のコードで処理する必要がある.
ライトtpdに戻ってmalloc関数の戻り値をassertで断言するのも、プログラムエラーではなく実行時エラーだと思います.だから、『Cとポインタ』という本ではmallocに対してNULLを返す処理は、エラーチェックディスペンサで処理されていると思います.
4、断言とバグ
断言は大きく分けて前置条件(Preconditions)、後置条件(Postconditions)、不変性条件(Invariants)
前置条件が成立せず、Assertion violationsが発生した場合、この関数を呼び出すコードにバグが存在し、できるだけ早く見つけて解決する必要がある.
後置条件が成立せず、Assertion violationsが発生した場合、(関数の)実装コードにバグがあり、できるだけ早く見つけて解決する必要がある.
例:
void doBlah(int x)
{
assert(x!=0);
....
}
このコードは、この関数の呼び出しがパラメータ0に入ることが不可能であることを示し、この場合、この関数を呼び出すコードにバグがあることを示す.
以上は自分の少しの理解で、达人の指摘を歓迎します!!!参照:How to use assertions in C
《 Writing Solid Code 》