I never got the idea of asserts -- why should you ever use them?
I mean, let\'s say I were a formula driver and all the asserts were things like security belt, helm
Because they make debugging easier.
The time consuming part of debugging is tracing a problem from the symptom you first notice back to the error in the code. Well written assertions will make the symptom you notice much closer to the actual code problem.
A very simple example would be a bug where you index past the end of an array and cause memory corruption which eventually causes a crash. It can take a long time to trace back from the crash to the offending index operation. However, if you have an assertion next to that index operation that checks your index, then your program will fail right next to the error, so you'll be able to find the problem quickly.
I use it mostly for tests during development. For instance, here is the smoke test of my utf-8 library Whenever I make a change in the library code I run the tests and if a bug is introduced an assert will trigger. Of course, I could have used a full-blown unit test framework, but for my purposes asserts are just fine.
Can't resist quoting "The indispensable Calvin and Hobbes" p. 180:
Before going down a steep hill like this, one should always give his sled a safety check.
Right.
Seat belts ? None.
Signals ? None.
Brakes ? None.
Steering ? None.
WHEEEEEE
I NEVER use assertion in my code, I hate them with passion. I understand the need for error checking and handling but to prevent an error that would crash your program by crashing your program yourself .... frankly I do not see the advantage.
Also leave one assertion in your code and murphy's law will ensure that it will, eventually, crash your program. I much prefer checking the data before I do processing with it and throw the appropriate exception so it is handled much like any other exceptional states or operation. This in my experience yielded software that was much more stable in the long run with deterministic behavior from the user's stand point.
You as a software engineer will know what to do when your program asserts out, most users will just get scared they broke something and will end up not using your software. So unless you are developing for engineers (which is quite possible) and even then...
From a usability stand point asserts are horrible, even if they are not "supposed" to happen we all know that eventually it will...
Ok... From all the comment and fire I am getting here I think I need to further explain my point of view because it is clearly not understood.
I did not say I was not checking for exceptions, weird values or just plain wrong states, I just said I did not use assertions because of the horrible way they tent to close the system from a end-user's perspective. Also most modern languages provide another, type-safe way to handle these situations, whey then would I use assert when a perfectly good exception would do the trick, and quite nicely so too.
In most production code I have seen out there I noticed mainly two ways to deal with this, buttering asserts all over the code and then leave a good bunch in production. This has the infuriating tendency to just close the application to the user, I have yet to see an Assert gracefully fail a system.... it just fails it ... boom... gone... end user just saying "WTF is a assertion failed error at address 0x330291ff!!!"
The other way, even worst if you ask me, was to just catch whatever was thrown and hide it under the carpet (ever seen these dreadful try-catch with empty braces !!)
NEITHER WAY will work to get a good stable system. Sure you can use asserts in your beta code and remove them all in your production code... but why the hell would you remove your safety nets because it is production. I would be very surprised that all these checks would cripple your system's performances.
Build yourself a good exception handling scheme and .. by god... LEAVE IT THERE, you will get much more meaningful information our of your system and if done appropriately always in context than having some deep library throwing asserts because something is missing.
This is especially true when creating libraries... to think you, the creator of the library, can decide when to bring down the whole system because something went wrong in the data that was thrown at you is incredibly selfish and narrow minded. Let the user of your library decide what is sufficiently important that it should warrant emergency failure.
so no... I do not use asserts... I use exceptions
And yes... usually the code that fails in production has rarely my name on top.
Assertions are invaluable while refactoring I think. If you want to replace alogrihm1() with algorithm2(), you could have them both and assert on the results being equal. You can then gradually phase out the algorithm1()
Asserts are also good for some changes that you might make quickly, but are not too sure of in the context of the state of the system. Setting up asserts for the assumptions you make, would quickly help you to point out the problem, if any.
It is debatable whether asserts should be stripped via using macros or the like in release, but that's what has been done in the projects I have worked on so far.
In Code complete is a section that says something like. Every time you write an if without any else you are maybe missing something.
It is like this code
int i = 1
i = i++
The common programmer will never think about what happens if i is negative in later code. There is the slightly chance of your code producing an overflow and languages like java will jump from max int to min int and you get a very big negative number. This are all the cases you normally say. Uh this will never ever happen. But what is your program doing if it happens? So if you know that there is something that you think will never happen test for it or against it and put an assert false in the else clause that will never happen instead of don't program the else statement. In this way your program should crash completely in the moment you aren't sure any more what it is doing. In production code there should be something different from rather crashing something like informing the user, the maintainer and then exiting.
Another use of assertions is contract driven design. You specify an contract with your interface and depending on your place in the program you assert your input but much more importing you are asserting your output two.
I agree with you that disabled assertions in production code make assertions rather useless. And the default assertions off in case of the java vm is a hazard in my opinion.