Most C++ compilers these days should have zero cost exception handling, meaning that the non-exceptional path should be free. This works by making the compiler add exception handler data to the executable file, ie. telling where the catch() blocks are. When an exception is thrown, the stack trace is analyzed and the appropriate catch handler is found by searching for the return addresses in the exception handler data.
This can make C++ with exceptions faster than C with error checks because there's no branches to check for every error condition. Using __builtin_expect for marking the error conditions as unlikely may mitigate this issue.
The cost is that you have to ensure that all your code is exception safe unless you are extremely careful to ensure that exceptions are only thrown in places you've expected and coded for.
Exception safe code is both difficult to write correctly and often has a significant run time cost.
Agreed on both accounts but the grandparent comment was talking about runtime performance penalty, which is gone (for the non-exceptional path) in modern implementations.
But yes: exception safety, even basic safety (don't leak resources or crash) is difficult, let alone strong exception safety (no side effects if exception occurs).
This can make C++ with exceptions faster than C with error checks because there's no branches to check for every error condition. Using __builtin_expect for marking the error conditions as unlikely may mitigate this issue.