Gianni said:
So now, exceptions are glorified cross function gotos. Probably not a
good thing.
Quite different to a goto.
When a failure occurs, it is often the case that you do not know how to
handle the error, and so you inform your caller. If you do it via error
codes, then the caller has to check the return value, and decide what to
do, possibly informing its caller via a return code.
This results in lots of checks of calls into function for errors that
rarely occur, and manually propagating the error up the call stack.
With exceptions, you can short-cut the call up the stack. This means
you deal with the error when you know how to do so.
I was on the fence for quite a while on exceptions and I'm now leaning
on a very minimal usage of exceptions. Opening a file is in almost
every case I have come across, not a case for using exceptions, even if
you expect the file to exist.
Often, yes. If for example the filename was provided on the command
line, to the program, and you do a bunch of stuff, then try to open the
file and it doesn't exist, rather than manually propagate the error up
the call stack with return codes you can just throw, and then catch it
near the top, and inform the user they can't spell.
It's also very unfortunate that exception specifiers are dynamically
handled rather than allowing the compiler to do a static analysis.
Yes, I would have preferred to have to explicitly specify anything that
a function could throw, and for the compiler to provide static analysis:
#include <iostream>
void fun1() {
throw "foo";
}
void fun2() throw() {
throw "bar";
}
void fun3() throw() {
fun1();
}
int main() {
try {
fun1();
} catch (char* e) {
std::cout << "This is expected to fail: " << e << std::endl;
}
try {
fun3();
} catch (char* e) {
std::cout << "This is NOT expected to fail: " << e << std::endl;
}
}
It's a shame that more analysis is not done to ensure that fun3 does not
throw. VC8 warns that fun2 throws, but does not warn that fun3 calls a
function that throws.
Multithreaded code is almost always impossible to manage using exceptions.
Surely you have to manage throwing, anyway?
I'm not trying to say exceptions are bad, I'm saying they're very
limited in utility. Also, I find it a fallacy that code is easier to
write. Handling exceptions correctly can get quite involved making the
code much more difficult to write if you have to write try/catch blocks
everywhere.
Exceptions are for exceptional situations, things which are really bad,
things you don't really know how to deal with. If you write code to
deal with it, it means you expect it to happen, in which case it may not
be best to consider it an exceptional situation.
The normal process of handling errors via return codes is often the most
practical way of dealing with an error, especially if the caller of the
function experiencing the error can deal directly with it.
If it really is exceptional, it's likely that you can't deal with it
directly at the call site, you may have to get 10 calls up the stack to
deal with it, so it's often more manageable to throw.
Anyhow, I'm sure that there are plenty o people who would debate this,
and I'm looking forward to a constructive one.
It could be interesting!
Ben Pope.