Of
course it costs something for this new feature; when an exception is thrown
there’s considerable run-time overhead. This is the reason you never want
to use exceptions as part of your normal flow-of-control, no matter how
tempting and clever it may seem. Exceptions should occur only rarely, so the
overhead is piled on the exception and not on the normally executing code. One
of the important design goals for exception handling was that it could be
implemented with no impact on execution speed when it
wasn’t
used; that is, as long as you don’t throw an exception, your code runs as
fast as it would without exception handling. Whether or not this is actually
true depends on the particular compiler implementation you’re using.
Exception
handling also causes extra information to be put on the stack by the compiler,
to aid in stack unwinding.
Exception
objects are properly passed around like any other objects, except that they can
be passed into and out of what can be thought of as a special “exception
scope” (which may just be the global scope). That’s how they go
from one place to another. When the exception handler is finished, the
exception objects are properly destroyed.