Removing assertions from release builds -- a bad idea?

Started by
71 comments, last by Conner McCloud 18 years, 6 months ago
Asserts serve no purpose in a final product.

Asserts are supposed to be used to catch programmer errors.

Presumably, after an assert fails, you fix the error causing it (if it can't be fixed because it has an external trigger, then it need replaceing with an exception).

There's no point in releasing an exectuable containing code to catch errors you've already fixed (any bugs in your program won't have corresponding assertion failures, else you'd know about the bug and have fixed it).


Advertisement
Quote:Original post by Nitage
There's no point in releasing an exectuable containing code to catch errors you've already fixed (any bugs in your program won't have corresponding assertion failures, else you'd know about the bug and have fixed it).


Are you ready to make the claim that your release code can never fail an assert condition, no matter what corner cases are reached?
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
I guess the amount of use asserts have in release build depends on your sense of 'customer support'.

If you remove asserts and your game crashes, at least Win XP already shows the nice user friendly equivalent of 'You are screwed..'. In some cases, the game may even stumble along, possibly allowing the user to save his game just before going down. In short, the user is screwed anyway, is letting him down easy really helpful?

However, if you intend to fix your bus and release patches (as more and more games do) then the crash information is probably vital for a quick bug fix.
Quote:Original post by DaBono
However, if you intend to fix your bus and release patches (as more and more games do) then the crash information is probably vital for a quick bug fix.


That's what exceptions are for.
In my mind, asserting on cases is there to help with the debugging process. If you are shipping a release build of the game, and want to catch really bad cases, use exceptions. In a lot of applications, there are good mixtures:


bool PerformSomeTaskWithAUserFile( const char* szFilename ){  // Everything before this should guarantee that the file  // pointed to is a valid file, but double check.  // None the less, if the file IS invalid, don't proceed.  // Only raise the warning so a tester can get a coder  // to figure out why this happened.  if ( IsFileValid( szFilename ) == false )  {    ASSERT_MSG( false, "File is invalid, this should not happen" );    return false;  }  // .. go on and do things with the file  return true;}


I often put assertions in to let the testers know that something unnexpected has happened. When they are testing the program they know to get a coder or log the bug. In release at least the case is handled somewhat. The function returns false and the caller knows something bad has happened and can report this case to the user, or also handle the case gracefully.

I'm not saying that I do this in all cases, but I certainly try to make applications fail with some sense of grace in release. The end user is much happier knowing that something was wrong with the file instead of getting an assertion that the file isn't valid and then crashing.

Just my two cents.

- S
The thing about the standard assertion handler is that it basically crashes the program while producing an error message. If you mean to leave assertions in the release build, you need to change this default behaviour somehow to do things like more gracefully clean up resources, especially things like file handles. In this case, a proper exception handling discipline would probably handle this cleanup. So if you do leave assertions in release, then you might as well implement your assertion mechanism in terms of exceptions.
Sphet -- that's a terrible use of assert, that should be a thrown exception that is handled higher up in the code.

SiCrane -- I don't think a release time assert should fail gracefully either. Just like a debug time assert, you die on the spot. The idea behind an assertion is that if it fails, you are already completely screwed. DaBono's suggestion of letting the user save their game is even worse, since if save games are affected by the mistake and are now in an inconsistent state, you've permanently fried the user's save game (or left it in a state that could damage future execution of your program). If in the situation that a crash is only a matter of time (be it milliseconds or minutes), you may as well assert and stop now.
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
So you want to leave an open file handle that potentially prevents the program from being uninstalled just because you didn't feel like cleaning up from a crash?
Quote:Original post by SiCrane
So you want to leave an open file handle that potentially prevents the program from being uninstalled just because you didn't feel like cleaning up from a crash?


Assertions are major problems, things that you believed were never possible. It's a reasonable assumption that if the assertion failed, you're about to crash. Your file handles are going to be left dangling anyway. And most OSes nowadays are able to release the file handles when a process dies, if it comes to that. It's between a crash and an assert->crash. May as well take the latter.
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
Thinking you're screwed is no reason not to make an attempt to clean up after yourself. And misbehaved programs on XP even with Service Pack 2 can still leave file handles in such a state that XP will refuse to delete the files even after reboots. Maybe Vista will be magical and wonderful and safe from programmer errors, but I somehow doubt it.

This topic is closed to new replies.

Advertisement