4
ASSERT(pointer);
pointer->x;

このコードでは、ASSERT が冗長に見えます。ポインタが NULL の場合、pointer->x はとにかく失敗します。私の主張は正しいですか?

4

7 に答える 7

33

アサーションの (主要ではないにしても) 重要な目的は、コード内の特定のポイントで保持されるはずの不変条件を文書化することです。不変条件が壊れている場合にプログラムを中止することもできるという事実assertは、非常に便利なものではありますが、ケーキのアイシングです。典型的なプログラムでは、アサーションの 90% は、明らかに失敗することがなく、決して失敗しないアサーションであると言えます。言い換えれば、assertはかなりの程度、一種の形式化されたコメント言語です。これらの「コメント」は、平易な英語ではなく、残りのコードが (C/C++) で書かれているのと同じ言語で書かれているという意味で形式化されています。

あなたのコードサンプルでは、​​ポインターがここで null であってはならないことを示すアサーションがあります。それがそこにある理由です。その意味で、これassertは冗長ではありません。

実行フローに関する限り、assertは常に冗長です。そのため、アサーションは通常、リリース バージョンのコードではコンパイルされません。リリースコードにもアサーションを保持することを妨げるものは何もありませんが、通常は特別な種類の「リリースアサーション」を導入することによって行われます。いずれにせよ、コードの主な機能をアサーションによって実行されるアクションに依存させることは、適切なプログラミング手法ではありません。コードの主な機能に関する限り、アサーションは冗長であると想定されています。

于 2009-12-23T23:41:26.867 に答える
19

はい、しかしpointer->x(私が推測するに) 制御されていない方法で失敗しますが、assertは失敗し、正確な場所を教えてくれます。

もちろん、ある意味でassert常に冗長です。

于 2009-12-23T23:31:28.163 に答える
3

いいえ、冗長ではありません。アサーションは、悪いことが起こる前に実行を停止します。一方、無効なポインターを逆参照すると、実際の破損が発生するか、少なくとも制御された中止ではなく、制御されていないセグメンテーション違反が発生する可能性があります。

于 2009-12-23T23:32:17.570 に答える
1

ASSERTC標準の一部ではないため、何でもかまいません

 #define ASSERT(x) do { \
     x = malloc ( sizeof *x ); \
     memset ( x, 0, sizeof *x );\
     } while ( 0 )

assertは別問題です。

デバッガーを呼び出すマクロを持っている人もいれば、ASSERT他のデバッグやロギングを行うマクロを持っている人もいれば、プリプロセッサーの文字列化機能を使用する人もいます。

マクロが重要かどうかを知るには、マクロが何をするかを実際に説明する必要があります。

于 2009-12-23T23:45:07.157 に答える
0

場合によっては、アサートをデバッグに使用できます http://simonwillison.net/2008/May/22/debugging/

于 2009-12-23T23:33:54.417 に答える
0

ASSERTまた、クラッシュを引き起こさない可能性のある無効または非論理的な条件をチェックするためにも使用できます。これは恐ろしく不自然な例です:

void cpu_hog(int duration)
{
    int start_time = (int) time(NULL);
    int end_time   = start_time + duration;

    ASSERT(end_time > start_time);  /* If this fails, "int" is too small. */

    while ((int) time(NULL) < end_time)
        ;
}

1 つの小さな注意: ほとんどの支持者はASSERT、コードを記述するときに行う仮定を検証するためだけに使用することをお勧めします (たとえば、ポインターが非 NULL である、または条件が発生しないなど)。一般に、(1)デバッグ ビルドにのみ存在し、(2) デバッグ コードをプロモートした場合でも、発生が予想されるユーザー関連のエラーまたは例外 (ディスクがいっぱいなど) をトラップするために使用することは勧めできません。本番環境に移行すると、条件を適切に処理する代わりにクラッシュします。ASSERTASSERT

于 2009-12-23T23:47:25.893 に答える
-1

ASSERT は失敗しません。ブレークポイントでデバッガーを停止するためにここにあります。これはリリース ビルドには影響しません。

于 2009-12-23T23:35:36.690 に答える