P
Pavel
Luca said:Now that I thought of it more, the case seems to be deserving deeper
analysis (I myself was a moderate proponent of exceptions before and now
I am having a second thought). This is because the exception-based
method of error reporting seems to break one of the declared principles
of C++ design: you only pay for the features you use. From this
viewpoint, this is what concerns me:
There are some cases in which error reporting via exceptions is essential to
make the code *faster* than non-exception-based alternatives, for example:
while (i < N) {
__try {
for (; i < N; i++)
a = log(b * c); // floating point math
} __catch(exCode() == OVERFLOW) { // overflow ex. from the hw
a = log(b) + log(c); // redo without overflow
++i;
}
}
There the time to make support for the exception handling is negligible, since
there is only one function call in the critical loop. The exception is costly,
when it occurs, but we assume that the occurrence is rare.
Alternatives to look for errors are less efficient, for example checking for
overflow inside the loop requires two floating point comparisons, which make the
solution relatively costly; while using log(a) + log(b) directly would
double the number of calls to log().
MSVC "structured" exceptions are different; I don't know whether they unwind the
stack same way as C++ exceptions do. If they do, I would like to look at the
disassembled piece of the binary you built with this snippet: the
innocently-looking "try" block may compile into something quite unexpected (and
more expensive that the regular error processing, especially if you replace
log() with a C++ function that might create C++ objects and throw exceptions of
its own).
As for the cost of the non-exception-based error processing, it never *has* to
be higher than a single "read" memory access plus a single conditional jump
(based on testing an integer or whatever is the fastest-checked type on a
system) on a "successful" code path; of course, poorly designed APIs can make it
arbitrarily high.
-Pavel