On 10/11/2013 11:50 AM, Quoth Nevin Liber:
If everything is good, where did the bad null pointer come from?? More likely than not it is due to another (undetected) broken invariant.
Possibly, but it's more likely that it came from an unchecked failure condition (by which I mean that a particular method can intentionally return null sometimes, but the developer forgot to check for that). Developers are in general notoriously bad at remembering to do the error checking.
It is up to the designer of the library to determine if passing parameters that make it impossible to set up the class invariant is reasonable or not. If it is reasonable, it is part of the contract, and no problem.
If it is reasonably possible for a method to detect that its input would cause it to violate the class invariant, then it should report that failure in a defined way without UB. The only defined way that a constructor can fail is to throw an exception. Therefore, if it is feasible for a constructor to detect that it has been given invalid input, it should throw an exception. The only time UB should be permissible is if it is not feasible to validate the input, or there is some compelling (and documented) performance reason to skip the validation. Otherwise the library designer is just being lazy. Given that we're talking about a simple null check here, there's no excuse to skip it.
If it was okay with it being null, why did it pass it to the non-null smart pointer?
You are referring to two different things as if they were the same. The "it" being ok with the pointer being null is the code further up the callstack (destructors via stack unwinding) while the "it" with the bug is the immediate caller of the non-null pointer that didn't validate the pointer-that-could-be-null after obtaining it from somewhere-that-could-be-null-because-it-didn't-use-a-not-null-pointer. And because the caller didn't think about it.
Could you please show us your universal catch handler that handles every possible programming error w/o aborting, including corruption that might happen during the stack unwinding?
Could you show how stack unwinding could possibly cause corruption? There's no reason for it to do so, certainly not merely in the face of a bug that led to a pointer being unexpectedly null. Sure, it's possible for there to be lots of bugs, and you're never going to have something that can comprehensively resolve everything. But buggy destructors are something that you tend to notice pretty early on during development. As to whether you can recover, as I said before it's very program-specific and you can't give something that would work generically. But you're more likely to be able to successfully recover in a program that operates on independent requests (eg. webserver) or that is specifically designed to track actions for possible rollback (eg. database) or something highly modular with subsystems that can be destroyed and recreated. It's probably not going to be feasible in something that has a lot of mutable shared state.