tags:

views:

413

answers:

4

Reading misc. tutorials related to SDL development I've found two different examples, doing the same thing, but in a different manner. I was wondering which of the two are you considering to be correct, judging from the perspective of code "security" and maintainability .

In the first example the programmer isn't using assert at all, but the code looks OK (at least for my eye):

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

In the second example the programmer [other] is using a different approach, something like (the code isn't exactly copy-paste):

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

Is it OK to "substitute" in the if conditions (from the first example) with asserts like in the second example ?

What's the right strategy (if there's any) ?

+4  A: 

assert should be used when things go awry, in an unexpected way. Usually if an assertion fails, it means there is a bug in the program. Assertions are not used for expected errors that can just happen (i.e. failed to open a file, failed to initialize something, and so on).

In the example you presented, assert doesn't seem like the most logical solution. When the program failed to init SDL it makes more sense to tell it to the user in a structured way than to throw an assertion (which can just cause a seg-fault on some systems).

Eli Bendersky
+3  A: 

Assert statements are typically used only for debug builds and will halt the program and often allow you to break into a debugger. It probably makes sense in the release build to still check for error conditions. One simple way might be like this:

assert( condition );
if ( !condition )
    handle error;
Mark Wilkins
Is it OK? both assert and conditional process exist at the same time?
sevity
Yes. An assert statement is typically implemented as just an if statement. If the condition is not true, it runs some code (e.g., __asm int 3; perhaps). It just means that in debug builds, it has to run two if statements.
Mark Wilkins
Yes, if you can detect and recover from the error condition, that code should definitely be there. If you don't expect that error to ever occur in practice, then the assert makes sense, too.
Mark Bessey
+18  A: 

It is not OK to do this substitution. The second example is wrong, because assert(x) gets expanded to nothing in non-debug builds (when NDEBUG is defined). This implies that the pointer checks in assert above are removed from the code in release builds. That is definitely wrong.

So, when should one use assert? It is useful for documenting and debugging. In a way, you're saying, "I am sure that this condition is true, and am putting it here as an assert to catch bad code during debugging, and to document the condition to the readers of the code".

So, there is a BIG difference between the two examples. For things like checking the return value of malloc, assert is wrong because there is no guarantee that they will return non-NULL, and as I have mentioned above, assert(x) means "I am completely sure x is true", and not just "If x is not true, it is bad". For this, one uses if(x) good(); else bad(); control.

SDL_Init and SDL_SetVideoMode can return -1 and NULL respectively.

Alok
assert() should only be used to catch programmer screw-ups; it signals such a screw-up by crashing the program, hitting the programmer on the head with a 2x4, and waving big red flags explaining what the screw-up was. This is a Very Good Thing To Do; see David Thielen's book "No Bugs", in which one of the chapters is titled, "Assert The World". Any troublesome condition an end-user could conceivably run into in a release version of the program should be handled with as graceful a recovery as possible, and certainly not bringing the program down in flames.
Bob Murphy
+1  A: 

I use assertion for documenting preconditions and postconditions. (identifying intention of the function)

like..

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

    double quotient = dividend/divisor;

    //postconditions 
    ASSERT(quotient>=0);
    return quotient;
}
sevity