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!