4

雑読。SDL 開発に関連するチュートリアル 2 つの異なる例を見つけました。同じことを別の方法で行っています。コードの「セキュリティ」と保守性の観点から判断すると、どちらが正しいと考えているのでしょうか。

最初の例では、プログラマーは assert をまったく使用していませんが、コードは (少なくとも私の目では) 問題ないように見えます。

int main(){
        SDL_Surface *screen;

        /** Initialize SDL */
        if(SDL_Init(SDL_INIT_VIDEO)!=0){
                fprintf(stderr,"Unable to initialize SDL: %s",SDL_GetError());
        }
        atexit(SDL_Quit);

        /** Sets video mode */
        screen=SDL_SetVideoMode(640,480,16,SDL_HWSURFACE);
        if(screen==NULL){
                fprintf(stderr,"Unable to set video mode: %s",SDL_GetError());
        }

        return (0);
}

2 番目の例では、[その他] のプログラマーが別のアプローチを使用しています (コードは正確にはコピー アンド ペーストではありません)。

int main(){
        SDL_Surface* screen;

        /** Initialize SDL */
        assert(SDL_Init(SDL_INIT_VIDEO)==0);
        atexit(SDL_Quit);

        /** Sets video mode */
        screen=SDL_SetVideoMode(640,480,16,SDL_HWSURFACE);
        assert(screen!=NULL);

        return (0);
}

2 番目の例のように、(最初の例の) if 条件を assert で「置換」しても問題ありませんか?

正しい戦略は何ですか (もしあれば) ?

4

4 に答える 4

25

この置換を行ってはいけません。2 番目の例は間違っています。非デバッグ ビルド (が定義されている場合) では何もassert(x)展開されないためです。これは、上記のポインター チェックがリリース ビルドのコードから削除されていることを意味します。それは間違いです。NDEBUGassert

では、いつ使用する必要がありますassertか?これは、文書化デバッグに役立ちます。ある意味では、「この条件が正しいと確信しており、assertデバッグ中に悪いコードをキャッチし、コードの読者に条件を文書化するためにここに置いている」と言っているのです。

したがって、2 つの例には大きな違いがあります。の戻り値をチェックするようなことについては、それらが非を返すという保証がないため、間違っていますmalloc。また、上で述べたように、「私は完全に真であると確信している」ことを意味し、単に「が真でない場合、悪い"。このために、コントロールを使用します。assertNULLassert(x)xxif(x) good(); else bad();

SDL_InitとをSDL_SetVideoMode返すことができます それぞれ。-1NULL

于 2009-12-26T15:41:24.987 に答える
5

assert予期しない方法で物事がうまくいかないときに使用する必要があります。通常、アサーションが失敗した場合は、プログラムにバグがあることを意味します。アサーションは、発生する可能性があると予想されるエラー (つまり、ファイルを開くことができなかった、何かを初期化できなかったなど) には使用されません。

あなたが提示した例でassertは、最も論理的な解決策とは思えません。プログラムが SDL の初期化に失敗した場合、アサーションをスローするよりも構造化された方法でユーザーに通知する方が理にかなっています (一部のシステムではセグ フォールトを引き起こす可能性があります)。

于 2009-12-26T15:38:12.890 に答える
3

assert ステートメントは通常、デバッグ ビルドにのみ使用され、プログラムを停止させ、多くの場合、デバッガーを中断できるようにします。リリース ビルドでもエラー状態をチェックすることはおそらく理にかなっています。簡単な方法の 1 つとして、次のようなものがあります。

assert( condition );
if ( !condition )
    handle error;
于 2009-12-26T15:38:41.093 に答える
1

前提条件と事後条件を文書化するためにアサーションを使用します。(関数の意図を特定する)

お気に入り..

double positive_division(double dividend, double divisor)
{
    //preconditions
    ASSERT(dividend>=0);
    ASSERT(divisor >0);

    double quotient = dividend/divisor;

    //postconditions    
    ASSERT(quotient>=0);
    return quotient;
}
于 2009-12-26T17:03:19.970 に答える