C++ exceptions are built on SEH. It will quite happily execute any C++ handlers along the way when unwinding.
Really, this is your misunderstanding.
I was stating a fact (it has been this way at least a decade). C++ exceptions are implemented using SEH functionality in VC++.
/EHa causes the compiler to emit code such that SEH exceptions are handled like C++ exception, meaning they'll be caught by catch(...). Plain and simple.
Superficially true. To be specific:
* SEH exception filter for catch(...) does not select only C++ exceptions anymore (which it normally would).
* Optimizer can not rely on throws anymore and needs to emit all the unwind code it normally would omit.
An SEH will not otherwise cause destructors to get invoked during unwinding, because the SEH mechanism knows nothing aout the C++ runtime model.
That is messed up. SEH does not need to know anything about the unwind payload - C++ exceptions or otherwise.
SEH are not C++ exceptions, unless you use /EHa.
This is completely backwards.
Only C++ exceptions invoke C++ destructors.
Incorrect.
You need to use try/catch (and not __try/__except) to use C++ exceptions.
Incorrect in principle. C++ exception catching is done via SEH exception records where C++ exceptions have the exception code 0xe06d7363. You are free to handle C++ exceptions in your __except - which, granted, is quite silly.
I suspect the compiler is just trying to save you from the consequences of your misunderstanding.
Incorrect. Compiler just can not do object unwinding in a function scope that also has __try ... which overloaded my sleepy brain - i just was not aware of that limitation (have Googled around since then and it is a well known limitation, but like i said - could not pinpoint any specific reason for it).
PS. You are well advised to assume i am not totally talking out of my ass. Example code:
struct Test {
Test() { out << L"new Test"; }
~Test() { out << L"del Test"; }
void panic() {
throw 42;
}
};
void snafu() {
out << L"shit's gonna hit the fan ...";
Test obj;
obj.panic();
}
int filter(LPEXCEPTION_POINTERS e) {
out << L"exception code: " << std::hex << e->ExceptionRecord->ExceptionCode;
// second parameter in c++ exceptions is a pointer to thrown object (plain int in this case)
out << L"C++ exception payload object: " << std::dec << *(int*)e->ExceptionRecord->ExceptionInformation[1];
// yeah, we will take anything - including the C++ exception.
return EXCEPTION_EXECUTE_HANDLER;
}
void test() {
__try {
snafu();
} __except(filter(GetExceptionInformation())) {
out << L"panic averted";
}
}
Output (compiled with the default /EHsc option) as one would expect:
shit's gonna hit the fan ...
new Test
exception code: e06d7363
C++ exception payload object: 42
del Test
panic averted
Cheers.