It's true that exceptions in C++ are more expensive than in other languages, often even in absolute terms, but that has nothing to do with problem at hand.
In GC'd language, implementing exceptions by simple non-local exit to catch/finally block is perfectly viable implementation strategy. It does not work so well in C++, where are implicit finally blocks that call destructors of local variables almost everywhere. To some extent this feature could be abused to produce stack-trace during the unwinding (but that necessarily involves injecting code to all functions in the program).
On the other hand, CL/Smalltalk-style condition systems sidestep this issue completely, by running the handler code before unwinding the stack. Windows' SEH allows you to do the same thing. And IIRC even in plain C++, handler for completely unhandled exception (that by default involves call to abort()) runs without stack unwinding (thus something along the lines of std::set_terminate (__gnu_cxx::__verbose_terminate_handler) gives you stacktraces for unhandled exceptions).
In GC'd language, implementing exceptions by simple non-local exit to catch/finally block is perfectly viable implementation strategy. It does not work so well in C++, where are implicit finally blocks that call destructors of local variables almost everywhere. To some extent this feature could be abused to produce stack-trace during the unwinding (but that necessarily involves injecting code to all functions in the program).
On the other hand, CL/Smalltalk-style condition systems sidestep this issue completely, by running the handler code before unwinding the stack. Windows' SEH allows you to do the same thing. And IIRC even in plain C++, handler for completely unhandled exception (that by default involves call to abort()) runs without stack unwinding (thus something along the lines of std::set_terminate (__gnu_cxx::__verbose_terminate_handler) gives you stacktraces for unhandled exceptions).