Pete Bartlett wrote:
On 4 October 2013 17:45, Eric Niebler
wrote: On 10/4/2013 9:20 AM, Matt Calabrese wrote:
but I definitely am against an exception for this type of programmer error.
This is the crux of it. If this condition really does represent a programmer error (and IMO in this case it does), then Matt is right. Throwing is wrong. Programmer error == bug == your program is already in some weird state. Continuing by throwing an exception and executing an arbitrary amount of code is not good.
I don't think this is always the case. For example, unexpected output from a parser should not be an indicator of an error in the global state.
There should be code between the two ensuring that the output of one doesn't violate the precondition of the other.
Precondition violations ==> assertions. Use BOOST_ASSERT. That gives people a way to hook the behavior while giving a sane default.
If throwing an exception when this is null is a bad idea, then not checking in release mode is surely a terrible one.
If the code isn't checking for precondition violations, then it isn't ready to handle the exception, either. If the programmer knows enough to handle the exception, then s/he knows enough to prevent it.
It is a relief to me that this is at least a subject of debate. I've read the doctorine of asserts-on-pre-condition- failure for years on forums/mailing lists, but never felt I can truly apply it in the systems I have to deal with in real-life.
I think you don't understand the "doctrine".
Even if you concentrate on errors that could only be possibly be client programmer error (as opposed to some weird environmental condition), it rarely seems to be the case that the purist view "this single thing is wrong so I can't trust _anything_ about my system, I have to end now, leave no logging entrails, or give the client any chance to do any sort of salvage" is the least-worst practical option. For me it is often the case that I do have to assume some entire subsystem is invalid (e.g. one entire thread) and have to throw a long way out (and, yes, execute destructors), but at least soldier on or shut down relatively cleanly. If the destructors go bad in this teardown then you end up calling abort due to the double-throw rule..but hey that's no worse than asserting in the first place!
If you violate a precondition, and the function scribbles on memory, for example, what do you know about the state of your system? Can you do anything safely? Everything you do from that time may be wrong, despite your hopes to the contrary. If code asserts on precondition violation, your application halts abruptly, you fix the problem in the calling code, and you retry. If your tests are incomplete, then you may still have latent bugs. Permitting code to continue doesn't mean it will work, for any reasonable definition of "work". If, like Thorsten, you advocate for an exception, you're no better off. You aren't any more likely to remember to handle that exception than you are to avoid violating the precondition. Your testing won't have triggered the exception, so you won't have verified your program's reaction in that case. The exception will blow out of the current thread, which will result in a call to std::terminate(). If other threads continue running, will they work right given that some shared state has been destroyed? Ultimately, you must account for preconditions in all of your code. If you would rather have an exception when you attempt to violate a precondition, so as to avoid an assertion firing or the optimized build's continuing in an unknown state, then wrap the code. Your wrapper can check for the precondition violation and throw an exception. The result is that you know you're calling your wrapper and must account for your exceptions. You should, of course, test against that exception, but at least it will be your own exception type which you should know to handle in main(), or your thread procedure, so you can report it.
As Thorsten says, devs are not infallible and customers don't like their apps going bang.. Is my experience atypical?
Your experience isn't atypical, but your reasoning about the "doctrine" seems faulty. _____ Rob Stewart robert.stewart@sig.com Software Engineer using std::disclaimer; Dev Tools & Components Susquehanna International Group, LLP http://www.sig.com ________________________________ IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.