As far as I know, there are no performance flaws, because I am sure that C ++ exceptions are implemented through SEH anyway. Everything you do allows the extension to receive exceptions at the OS level. However, there is one major drawback that is affected by the two.
You would normally use __tryand __exceptto detect SEH exceptions; more info here . Note: here's a flaw: exceptions caught this way don't trigger destructors. However, you can use the function _set_se_translatorto translate SEH exceptions to C ++ exceptions.
Here is something from one of my projects that does this (uses Boost and C ++ 0x in MSVC 2010):
bool ignore_exception(unsigned pCode)
{
const unsigned ignoreList[] = {EXCEPTION_BREAKPOINT,
EXCEPTION_FLT_DENORMAL_OPERAND, EXCEPTION_FLT_DIVIDE_BY_ZERO,
EXCEPTION_FLT_INEXACT_RESULT, EXCEPTION_FLT_OVERFLOW, EXCEPTION_FLT_UNDERFLOW,
EXCEPTION_INT_OVERFLOW, EXCEPTION_SINGLE_STEP};
auto result = std::search_n(std::begin(ignoreList), std::end(ignoreList),
1, pCode);
return result != std::end(ignoreList);
}
std::string code_string(unsigned pCode)
{
switch (pCode)
{
case EXCEPTION_ACCESS_VIOLATION:
return "Access violation";
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
return "Out of array bounds";
case EXCEPTION_BREAKPOINT:
return "Breakpoint";
case EXCEPTION_DATATYPE_MISALIGNMENT:
return "Misaligned data";
case EXCEPTION_FLT_DENORMAL_OPERAND:
return "Denormalized floating-point value";
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
return "Floating-point divide-by-zero";
case EXCEPTION_FLT_INEXACT_RESULT:
return "Inexact floating-point value";
case EXCEPTION_FLT_INVALID_OPERATION:
return "Invalid floating-point operation";
case EXCEPTION_FLT_OVERFLOW:
return "Floating-point overflow";
case EXCEPTION_FLT_STACK_CHECK:
return "Floating-point stack overflow";
case EXCEPTION_FLT_UNDERFLOW:
return "Floating-point underflow";
case EXCEPTION_GUARD_PAGE:
return "Page-guard access";
case EXCEPTION_ILLEGAL_INSTRUCTION:
return "Illegal instruction";
case EXCEPTION_IN_PAGE_ERROR:
return "Invalid page access";
case EXCEPTION_INT_DIVIDE_BY_ZERO:
return "Integer divide-by-zero";
case EXCEPTION_INT_OVERFLOW:
return "Integer overflow";
case EXCEPTION_INVALID_DISPOSITION:
return "Invalid exception dispatcher";
case EXCEPTION_INVALID_HANDLE:
return "Invalid handle";
case EXCEPTION_NONCONTINUABLE_EXCEPTION:
return "Non-continuable exception";
case EXCEPTION_PRIV_INSTRUCTION:
return "Invalid instruction";
case EXCEPTION_SINGLE_STEP:
return "Single instruction step";
case EXCEPTION_STACK_OVERFLOW:
return "Stack overflow";
default:
return "Unknown exception";
}
}
void stack_fail_thread()
{
std::cerr << "Unhandled exception:\n"
<< code_string(EXCEPTION_STACK_OVERFLOW) << '\n';
std::cerr << "Terminating." << std::endl;
std::exit(EXIT_FAILURE);
}
void exception_translator(unsigned pCode, _EXCEPTION_POINTERS*)
{
if (pCode == EXCEPTION_STACK_OVERFLOW)
{
boost::thread t(stack_fail_thread);
t.join();
}
else if (!ignore_exception(pCode))
{
BOOST_THROW_EXCEPTION(std::runtime_error(code_string(pCode)));
}
}
void hook_signals()
{
_set_se_translator(exception_translator);
}
I took off a few things, but you understood this idea. You can extract all the same information in this way.