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

Sebastian Redl sebastian.redl at getdesigned.at
Mon May 26 21:11:45 UTC 2008


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



More information about the cxx-abi-dev mailing list