3 ms·
A boundary might not be enforceable in an absolute sense but the language should be able to tell when the boundary is crossed. An exception caught in main() th
by makecheck 10y ago
A boundary might not be enforceable in an absolute sense but the language should be able to tell when the boundary is crossed. An exception caught in main() that the compiler could automatically tag as having crossed a particular library or compilation unit would be infinitely more useful for debugging than what we have now.
What makes a library sufficiently buggy? The set of conditions leading to a crash from an exception at run time may not be known to the library maintainer, even in a “good” library. The crash in your particular program, caused by the library, may not occur for awhile, after which you already depend on the API. With a normal error-handling scheme, this would still be OK because you could trace the error.
Programs can already crash in enough ways, without C++ introducing more. I can debug even severe memory errors in fairly straightforward ways (e.g. trap in debugger, or run "valgrind", or other instruments). I hate debugging a “crash” that is essentially C++ converting a trivial mistake from someone’s error-handling code into a fatal, untraceable run time error. When I see terminate() I know I have a problem. I essentially have to start using "grep" for every possible "throw" statement (hopefully finding something in recently-committed code), trying to match functions that might be related to what the program seemed to be doing when it died. And since C++ exceptions provide very little help when debugging, one has to go to extra effort to add information to every exception (which is useless if the exception at run time didn’t come from your own code).
C++ exceptions are just not “better”, like a lot of C++ changes. They can’t break crucial debugging mechanisms like stack-traces and expect the result to be better.
- gpderetta 10y ago> When I see terminate() I know I have a problem. I essentially have to start using "grep" for every possible "throw" statement What debugger are you using that doesn't provide a full stack trace on an uncaught exception?
- slededit 10y agoThere's a surprising number of people still relying on printf debugging. With distributed systems the slightly more advanced version: log based debugging is getting even more common.
- maxlybbert 10y agoI realized after I posted my last question that a language could convert an unexpected exception into some other notice that "something went wrong" (e.g., another exception). But if that behavior is ever triggered, it's not clear what you can do. You have a library reporting that (1) it detected an internal problem AND (2) it did not handle that problem. Any objects you have from that library might be affected, so you can't reliably call functions on them. If the library provides a way to deallocate its objects ( https://blogs.msdn.microsoft.com/oldnewthing/20060915-04/?p=29723 https://blogs.msdn.microsoft.com/oldnewthing/20060915-04/?p=... ), you can't trust that it will work. Letting the objects fall out of scope isn't even safe. By the way, you can get very close to this behavior today with `std::set_unexpected` ( http://www.cplusplus.com/reference/exception/set_unexpected/ http://www.cplusplus.com/reference/exception/set_unexpected/ ). That page says that the function you set as the unexpected handler must "end either by terminating (calling `terminate` or some other method, such as `exit` or `abort`) or by throwing an exception (even rethrowing the same exception again). If the exception thrown (or rethrown) is not in the function's dynamic-exception-specification but `bad_exception` is, a `bad_exception` is thrown" (emphasis added). * > Programs can already crash in enough ways, without C++ introducing more. ... When I see terminate() I know I have a problem. I essentially have to start using "grep" for every possible "throw" statement (hopefully finding something in recently-committed code), trying to match functions that might be related to what the program seemed to be doing when it died. And since C++ exceptions provide very little help when debugging, one has to go to extra effort to add information to every exception (which is useless if the exception at run time didn’t come from your own code). For the record, I'm not really a fan of exceptions or fancy error handling code. I subscribe to the school of thought that you probably have a main loop (which handles requests, or waits for user input, etc.) and that loop should have your single try/catch block ( http://www.artima.com/intv/handcuffsP.html http://www.artima.com/intv/handcuffsP.html ). You handle exceptions by giving up on what you were trying to do, and perhaps letting the user know. You then go to the next loop iteration. That is, I almost never see a need for two try/catch blocks in a program ( https://blogs.msdn.microsoft.com/ericlippert/2008/09/10/vexing-exceptions/ https://blogs.msdn.microsoft.com/ericlippert/2008/09/10/vexi... ). Error handling code is especially notorious for not being tested and therefore not doing what it should. Therefore, error handling code beyond "abandon the current request" is fishy to me. And I agree that one of the few things I miss when I work in C++ is exceptions that carry a lot of information automatically. In C++, if you want the exception to carry file/line number information, you have to add it yourself (probably via a macro: "#define THROW_EX(X) throw AppException((X), __FILE__, __LINE__)" or something similar). And that doesn't even address nested exceptions. I rely on a lot of logging, and the ability to reliably reproduce the problem while running it in a debugger. I believe the Committee, so far, has avoided bringing exceptions on par with you see in other languages because doing so would have an unusually high execution and/or implementation cost compared to other aspects of C++. It's entirely possible that this decision will be revisited: C++14 and C++17 feel to me like they were very strongly influenced by Java.