On 9 October 2013 18:23, Gavin Lambert
On 10/10/2013 7:58 AM, Quoth Nevin Liber:
When I say one should assert on a detected precondition failure, it's really shorthand for putting the system into a known state. A mission critical system, for instance, might do something vastly more complicated than aborting.
I just don't see how throwing, which normally involves running code dependent on state, accomplishes this.
Throwing unwinds out of the current call stack to some higher level point of code that has declared that it is prepared to handle errors in some meaningful way.
In general, destructors are written assuming the invariants of the class hold on entry to the destructor. In order for what you say about stack unwinding to be true, you have to assume that the null pointer isn't due to a broken invariant somewhere else. Where is your evidence that no other object or program invariants are broken? Throwing pretty much means you are addressing the symptom and assuming there is no deeper underlying problem.
I'm all for early termination when the developer is around to sort it out immediately. But that's easy too -- just configure a debugger to intercept exceptions immediately when thrown. But instant termination is not a good user experience.
Data corruption is a far worse user experience. This morning for instance: I was listening to iTunes Radio and then switched to an audiobook. Due to a bug, I watched the music app promptly forget my bookmark in the audiobook (there was even an animation which rewound the position to the start of the audiobook) just before it decided to play my iTunes Radio station with the audiobook graphic. I would much rather have had it crash than forget my bookmark. (And no, I would not want my phone to crash because of it. I expect a well designed system to have process level resiliency, because the amount of shared state is minimized between processes.) -- Nevin ":-)" Liber mailto:nevin@eviloverlord.com (847) 691-1404