First, the performance difference can be huge. In one project our asserts literally caused a 3x slowdown. But they helped us uncover some really pesky bugs.
Which is exactly the point.
Asserts are there to help you catch bugs. And because they are removed in release builds, we can afford to put a lot of them in without worrying about performance. If you're not there to actually act on any failed assertions, they become worthless, so we might as well remove them.
Even catching the error and throwing an exception isn't really a solution. The program logic is flawed, and even if we handle the exception, the program is still broken.
What asserts basically boil down to is "Why bother catching errors you can't handle?"
Some errors must be caught during development. If they slip past testing and into the release build used by a customer, the program is just broken, and no amount of runtime error-checking is going to fix it.
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, helmet, etc.
Yes, that's a good example of when not to use an assert. These are things that might actually go wrong at runtime, and which need to be checked. Your formula one driver might forget some security precaution, and if he does, we want to halt the whole thing before anyone gets hurt.
But what about the check to see that the engine is installed? Do we need to check thatduring the race?
Of course not. If we get into the race without an engine, we're screwed, and even if we detect the error, it's too late to do anything about it.
Instead, this is an error that must be caught during development or not at all. If the designers forget to put an engine in their car, they need to detect this error during development. That's an assert. It's relevant to the developers during development, but afterwards, the error must not exist, and if it does, there's nothing we can do.
That's basically the difference. An exception is there to help the user, by handling errors that can be handled.
An assert is there to help you, by alerting you to errors that must never occur in the first place, that must be fixed before the productcan be shipped. Errors that do not depend on user input, but on your code doing what it is supposed to do.
The square root of four must never evaluate to three. The error is simply impossible. If it does occur, your program logic is just broken. It doesn't matter how much error handling we wrap around it, it's something that must be caught during development or not at all. If we used exception handling to check for this error and handle it, what is the exception going to do? Tell the user "the program is fundamentally broken. Don't ever use it"?
An email from the developer could have achieved that. Why bother building it into the program code? That's an example of a problem that simply must not occur. If it does, we have to go back and fix the program. No other form of error handling is possible.
But some errors, like being unable to open a file for reading, are possible. Even though it might be a bad thing if it happens, we have to accept that itcan happen. So we need to handle it if it does.
Asserts are for catching the errors that can't possibly happen.
http://stackoverflow.com/questions/1081409/why-should-i-use-asserts