Catching C++ Exceptions in D

Jakob Ovrum via Digitalmars-d digitalmars-d at puremagic.com
Tue Jan 5 10:22:56 PST 2016


On Tuesday, 5 January 2016 at 17:23:38 UTC, Walter Bright wrote:
> We have a design now, driven by:
>
> 1. compatibility with best practice exceptions in C++ (i.e. 
> never catch by value, etc.)
>
> 2. minimizing implementation difficulty
>
> 3. fitting in with D semantics
>
> 4. pushing as much as we can into the C++ compiler
>
> ----------------------------------------------------------
>
> C++ exceptions cannot be thrown from D. If you must throw a C++ 
> exception, write and call a C++ function to do it.

Because C++-throw copies the exception and thus slices base class 
references, this is actually quite inconvenient. There's no One 
Helper Function that can handle a whole swath of cases. Just 
wanted to mention it, not saying this should be an important or 
priority feature, it's just an inconvenience after all.

> D code can only catch C++ exceptions declared as:
>
>     extern (C++) class Identifier { ... }
>
> Best practice in C++ is catching by const&, and D's classes fit 
> right in with that.

Well, except for the const part. D exceptions are completely 
broken when it comes to const and immutable. It seems to have 
been overlooked during the transition to D2.

> At the exit of a catch clause, the destructor on the caught C++ 
> exception will be run, as would be expected by C++ programmers.
>
> Because of running the destructors, C++ exceptions cannot be 
> caught in @safe code.

Nice.

> Function bodies cannot mix catching C++ and D exceptions. (The 
> reason is C++ catch types need to be distinguished from D catch 
> types, and the most straightforward method to deal with that is 
> have a different 'personality' function for functions that 
> catch C++ exceptions.) However, nested functions can catch 
> different ones than their enclosing function.

Nice.

Thanks for doing this. I'm excited about C++ interop. There was a 
project called OpenMorrowind which dropped D1+C++ in favour of 
just C++ because the C interface was too tedious. I bet if they 
had what we have now they wouldn't have done that (assuming we 
fix the mangling bugs for C++ function templates and then provide 
stdc++ bindings).

Switching to DWARF has another benefit - it allows throwing D 
exceptions past C stack frames. Some people seem to think this is 
always wrong, but some C libraries are designed to support 
throwing or long jumping from certain callbacks, including libev 
and liblua. This tremendously helps the usability of D wrappers 
around such libraries. Currently I work around it by providing 
custom-compiled binaries of the C libraries with intact stack 
frames. This is also cause to be sad about our DWARF support 
being limited to Linux64.

Anyway, thanks!


More information about the Digitalmars-d mailing list