4

阅读杂项。与 SDL 开发相关的教程 我发现了两个不同的示例,它们做同样的事情,但方式不同。从代码“安全性”和可维护性的角度来看,我想知道您认为这两者中的哪一个是正确的。

在第一个示例中,程序员根本没有使用断言,但代码看起来不错(至少在我看来):

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);
}

在第二个示例中,程序员 [other] 使用了不同的方法,例如(代码不完全是复制粘贴):

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);
}

可以用第二个示例中的断言“替换” if 条件(来自第一个示例)吗?

什么是正确的策略(如果有的话)?

4

4 回答 4

25

做这个替换是不行的。第二个例子是错误的,因为在非调试版本(定义时)中assert(x)被扩展为空。NDEBUG这意味着assert上面的指针检查已从发布版本的代码中删除。那绝对是错误的。

那么,什么时候应该使用assert呢?它对于记录调试很有用。在某种程度上,你是在说,“我确信这个条件是正确的,我把它放在这里是assert为了在调试期间捕获错误代码,并将条件记录给代码的读者”。

因此,这两个示例之间存在很大差异。对于检查 , 的返回值之类的事情是错误的malloc,因为assert无法保证它们会返回非不好”。为此,人们使用控制。NULLassert(x)xxif(x) good(); else bad();

SDL_Init并且SDL_SetVideoMode可以分别返回-1NULL

于 2009-12-26T15:41:24.987 回答
5

assert应该在事情​​出错时以意想不到的方式使用。通常,如果断言失败,则意味着程序中存在错误。断言用于可能发生的预期错误(即无法打开文件,无法初始化某些内容,等等)。

在您提供的示例中,assert这似乎不是最合乎逻辑的解决方案。当程序无法初始化 SDL 时,以结构化的方式告诉用户比抛出断言(这可能会导致某些系统上的 seg-fault)更有意义。

于 2009-12-26T15:38:12.890 回答
3

Assert 语句通常仅用于调试构建,并且会停止程序并经常允许您闯入调试器。在发布版本中仍然检查错误条件可能是有意义的。一种简单的方法可能是这样的:

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 回答