Re: [cxx-abi-dev] ABI modification for exception propagation
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [cxx-abi-dev] ABI modification for exception propagation



Mark Mitchell wrote:
Ideally, it should be possible to freely mix old and new object files in a single application. It should be possible to throw an exception in an old file and catch it in a new one, and vice versa.
Hmm, I think that's not possible. Definitely not in the separation model. It might be possible in the other approach, where the exception object plus the __cxa_exception are copied whole, but I'm doubtful even of that. That was a chance that was missed when it was decided that the exception class gave sufficient version information. That was a mistake. There is simply no way for the new code to know whether the new, additional fields are present or not unless the exception class is changed, in which case the old code will reject the exceptions. Unless the vendor was smart enough to build the class test with versioning in mind, but at least GCC didn't.

Old code can obviously catch exceptions from new code as foreign exceptions. What is also possible is to make it so that new code can catch exceptions from the old code.
However, even that is problematic. Consider:

old.cpp:
void oldfun() { if(rand() % 2) throw foo(); }

new.cpp:
void newfun() { throw foo(); }

main.cpp:
int main()
{
 try {
   oldfun();
   newfun();
 } catch(foo&) {
   exception_ptr ep = current_exception();
   if(ep) std::cout << "yes\n";
   else std::cout << "no\n";
 }
}

Suppose that old.cpp was compiled with an old compiler, and new.cpp and main.cpp with a new compiler. Because the ABI change is necessary to make exception_ptr work, obviously you can't get an exception_ptr for an old exception. But this means a) that current_exception() can fail for - to normal users - completely impenetrable reasons and b) that the code is not standards-compliant (if there's a current exception, current_exception must return a pointer to that or to a bad_alloc).

Basically, the code would print "yes" half the time. This is such a gross violation of the principle of least surprise that I honestly would consider not providing this half-compatibility at all the better choice. Let these exceptions be caught only as foreign exceptions, which lie outside the realm of the C++ standard and where current_exception can return null without causing a headache.

Sebastian