4 ms·
From the CFG perspective, try..catch is strictly weaker than goto (you can't build irreducible control flow with it for example). And, I mean, any return is bas
by edflsafoiewq 8y ago
From the CFG perspective, try..catch is strictly weaker than goto (you can't build irreducible control flow with it for example). And, I mean, any return is basically a non-local goto for which the destination is unknown at compile-time.
Your story seems strange since I think one of the best features of exceptions is that if you don't catch them, you always get a full stack trace which is a great boon for debugging. If you bubble up error returns, the only contextual information you get about where the error occurred is what every caller attaches to the return. But I have had terrible trouble getting stack traces (or types) from Python exceptions when they cross a process boundary so maybe that's it.
(I have no strong opinion about whether exceptions are good or bad myself.)
- notacoward 8y ago> you always get a full stack trace You get a trace from where it was caught. Where was it thrown? Nobody knows. To be fair, that's the same as you'd get with error returns, but at least those dozen layers in between had a chance to see and log the error. Or in a callback-based system you do get a trace from where the error originated. The problem is that the act of throwing an exception destroys practically all information other than what you put in the exception yourself, and very few programmers implement exceptions in a way that provides as much information as is already available with error returns. Exceptions should be exceptional - rare events that don't get thrown or caught as part of normal operation. When every possible outcome of calling a function is reflected as a different exception, even if it's a fairly common case, that's when even simple control flows turn into big piles of random jumps.
- edflsafoiewq 8y agoNo, you get a trace to where it was thrown.
- anyfoo 8y agoIn C++?
- edflsafoiewq 8y agoYes? Is there a difference in terminology here? Obviously you get a trace to the point of the throw. ~ $ cat a.cxx int a() { throw "a"; } int b() { return a(); } int main() { b(); } ~ $ clang++ -g a.cxx && gdb -ex r -ex bt a.out < ...snipped... > #6 0x0000555555554779 in a () at a.cxx:1 #7 0x0000555555554789 in b () at a.cxx:2 #8 0x000055555555479d in main () at a.cxx:4
- anyfoo 8y agoThere is no catch in your example. I thought the point was that in C++, preserving the stack trace when having caught an exception is rather non-trivial. Exceptions that don't get caught usually allow you to get the stack trace through a crash report/core dump/whatever, but then there's not much difference between an uncaught exception and a plain abort().
- edflsafoiewq 8y agoYes, I said "if you don't catch them you always get a full stack trace". The comparison was between returning error values and exceptions, not between exceptions and abort. The difference is with abort is of course that once you are alerted to the error by seeing it be uncaught, you can insert an appropriate handler for it. A file-open function can throw on file not found but I will not very happy if it aborts.
- anyfoo 8y agoAh, after reading the full thread, that is actually what you said, and I don't really know what the point of the commenter you replied to was, now...
- Forge36 8y agoYou should be, however I've delt with subtle bugs caused by throwing errors across the RPC boundary. Those exceptions weren't logged in the sending side. The solution in the recieving side was a try catch, which ate the "connection terminated" exception. And instead of a stack trace, I'm dealing with broken connections later on in a different RPC.