I thought that I had successfully extricated myself from the assertion debate with this post. But Len has added a comment to this post that really begs for refutation :-)
In his comment, Len says that he agrees with Herb Sutter's C++ Coding Standards, except for item 68 - "Assert liberally to document internal assumptions and invariants". To summarise the parts of his argument with which I disagree, Len's first claim is that using assertions to validate internal assumptions leads to a tendency to rely upon assertions at the cost of better design. His second claim is very similar - he spends a lot of time reducing ambiguity in his code, and these efforts reduce or eliminate the need for assertions.
My first point is that mediocre developers will screw-up their designs, regardless of whether they use assertions. So using assertions is a way of forcing you to stay humble - they remind you that you aren't as good a developer as you thought you were. In a previous life, I was a professional chess player. Professional chess players tend to be much more humble than their developer counterparts, because our mistakes are usually brutally exposed by our opponents and so they directly cost us money. Now I think that if Len lost £100 or £1,000 for every un-caught bug in his code, and additionally an evil nemesis was actively and ruthlessly searching for those bugs, he might have a rather different stance on assertions...
But, for the sake of argument, let's assume that Len really can leap tall buildings with a single bound and he really is an uber-programmer.
In time, less uber developers can and will modify Len's sparkling bug-free code. Without assertions to document the internal state of Len's code and the assumptions that were made when the code was written, these developers will almost certainly create bugs that would otherwise have been caught. These developers won't unit-test to the same quality as Len, they won't refactor to the same degree, and they certainly won't understand Len's code as well as he did when he wrote it.
So it seems to me that ANY argument against assertions that relies mainly on developer skill is fundamentally broken. Humans aren't designed to program computers, and they WILL ALWAYS make mistakes.
UPDATED: To represent Len's point of view, because I don't have comments on my blog: He feels a little mis-represented, but says I have a point. His major point is why do we need assertions that are testing for the same problems as unit tests? My feeling is that unit tests measure what your code should do, whereas assertions check for stuff that should never happen in reality. I think it's a waste of time to code and somehow test expensive (compared to relatively cheap assertions) unit tests for stuff that shouldn't happen.
But, as Len says, there is no right answer. It's perhaps more about style and "religion" than anything else. Here's more from Noel and Len.