September 12, 2014
On 12/09/14 07:01, Iain Buclaw via Digitalmars-d wrote:

> Libunwind + handling foreign exceptions you can do this.  And is
> beneficial in that it works with any other languages that use libunwind,
> such as gccgo.

And Objective-C.

-- 
/Jacob Carlborg
September 12, 2014
On Friday, 12 September 2014 at 06:56:29 UTC, Jacob Carlborg wrote:
> On 12/09/14 05:25, deadalnix wrote:
>
>> Yes, that is pretty why I limited myself to the "unwind properly but do
>> not catch" option. This one would require to mess with the innards of
>> various C++ runtime.
>
> On 64bit Objective-C can catch C++ exceptions. But I don't think you can do anything with the exception, i.e. it uses the following catch syntax:
>
> @catch(...) {}
>
> Would that be easier?

I think the trick is setting up the stack frame in such a way that the C++ exception mechanism knows there's a catch block available at all.  From there, we should be able to use the standard interface-to-class method to call virtual functions on the exception object, and hopefully the C++ runtime will handle cleanup for us.

I imagine the easiest thing would be to find a platform where we already know how exceptions are thrown in C++ (DMC on Windows?) and figure out how to make it work in D.  With inner functions and inline asm, I'm sure it's possible to make this work without compiler changes.  I don't know whether the unwinding mechanism differs across compilers or even compiler versions for a particular platform though.  This may all end up being a bit brittle.
September 12, 2014
Am Fri, 12 Sep 2014 15:55:37 +0000
schrieb "Sean Kelly" <sean@invisibleduck.org>:

> On Friday, 12 September 2014 at 06:56:29 UTC, Jacob Carlborg wrote:
> > On 64bit Objective-C can catch C++ exceptions. But I don't think you can do anything with the exception, i.e. it uses the following catch syntax:
> >
> > @catch(...) {}
> >
> > Would that be easier?
> 
> I think the trick is setting up the stack frame in such a way that the C++ exception mechanism knows there's a catch block available at all.  From there, we should be able to use the standard interface-to-class method to call virtual functions on the exception object, and hopefully the C++ runtime will handle cleanup for us.

What exception object?

throw "bad things happened";

-- 
Marco

September 12, 2014
Am Thu, 11 Sep 2014 17:35:25 -0700
schrieb Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org>:

> Hello,
> 
> 
> We are racking our brains to figure out what to do about exceptions thrown from C++ functions into D code that calls them.
> 
> A few levels of Nirvana would go like this:
> 
> 0. Undefined behavior - the only advantage to this is we're there already with no work :o).
> 
> 1. C++ exceptions may be caught only by C++ code on the call stack; D code does the stack unwinding appropriately (dtors, scope statements) but can't catch stuff.
> 
> 2. D code can catch exceptions from C++ (e.g. via a CppException wrapper class) and give some info on them, e.g. the what() string if any.
> 
> Making any progress on this is likely to be hard work, so any idea that structures and simplifies the design space would be welcome.
> 
> 
> Andrei

I would say aim for 1. I wouldn't expect any less or any more. Exception handling seems to have a platform wide standard on major OSs that D should follow (e.g. libunwind helps with this on GCC dominated systems), but dealing with C++'s "throw anything" seems overkill to me for the next milestone in C++ interop. After all there could be exceptions using multiple inheritance, templated objects or basic data types thrown from the C++ side.

-- 
Marco

September 12, 2014
On Fri, Sep 12, 2014 at 06:19:54PM +0200, Marco Leise via Digitalmars-d wrote:
> Am Fri, 12 Sep 2014 15:55:37 +0000
> schrieb "Sean Kelly" <sean@invisibleduck.org>:
> 
> > On Friday, 12 September 2014 at 06:56:29 UTC, Jacob Carlborg wrote:
> > > On 64bit Objective-C can catch C++ exceptions. But I don't think you can do anything with the exception, i.e. it uses the following catch syntax:
> > >
> > > @catch(...) {}
> > >
> > > Would that be easier?
> > 
> > I think the trick is setting up the stack frame in such a way that the C++ exception mechanism knows there's a catch block available at all.  From there, we should be able to use the standard interface-to-class method to call virtual functions on the exception object, and hopefully the C++ runtime will handle cleanup for us.
> 
> What exception object?
> 
> throw "bad things happened";
[...]

Yeah, in C++, you can throw *anything*. Including ridiculous things like `throw NULL;` or `throw 3.14159;`. There's no method for that! What we might end up doing, might be to wrap the C++ exception in a D exception that contains a pointer to the C++ type along with whatever type info we can glean from the C++ runtime. We probably won't be able to do much more than that.


T

-- 
Bomb technician: If I'm running, try to keep up.
September 12, 2014
On Friday, 12 September 2014 at 16:37:43 UTC, H. S. Teoh via Digitalmars-d wrote:
> On Fri, Sep 12, 2014 at 06:19:54PM +0200, Marco Leise via Digitalmars-d wrote:
>> Am Fri, 12 Sep 2014 15:55:37 +0000
>> schrieb "Sean Kelly" <sean@invisibleduck.org>:
>> 
>> > On Friday, 12 September 2014 at 06:56:29 UTC, Jacob Carlborg wrote:
>> > > On 64bit Objective-C can catch C++ exceptions. But I don't think you can do anything with the exception, i.e. it uses the following catch syntax:
>> > >
>> > > @catch(...) {}
>> > >
>> > > Would that be easier?
>> > 
>> > I think the trick is setting up the stack frame in such a way that the C++ exception mechanism knows there's a catch block available at all.  From there, we should be able to use the standard interface-to-class method to call virtual functions on the exception object, and hopefully the C++ runtime will handle cleanup for us.
>> 
>> What exception object?
>> 
>> throw "bad things happened";
> [...]
>
> Yeah, in C++, you can throw *anything*. Including ridiculous things like
> `throw NULL;` or `throw 3.14159;`. There's no method for that! What we
> might end up doing, might be to wrap the C++ exception in a D exception
> that contains a pointer to the C++ type along with whatever type info we
> can glean from the C++ runtime. We probably won't be able to do much
> more than that.

How about

    try {
        my_cpp_func();
    } catch(CppException!(const(char)*) e) {
        writeln(e.payload.fromStringz());
    }

?

Btw, how does implicit conversion work with `catch` in C++? I.e., if you throw a `char*`, will it be caught when you catch `const char*`? This can not be handled easily with such a template, as we would need to catch both `CppException!(const(char)*)` and `CppException!(char*)`.
September 12, 2014
Am Fri, 12 Sep 2014 17:57:39 +0000
schrieb "Marc Schütz" <schuetzm@gmx.net>:

> How about
> 
>      try {
>          my_cpp_func();
>      } catch(CppException!(const(char)*) e) {
>          writeln(e.payload.fromStringz());
>      }
> 
> ?
> 
> Btw, how does implicit conversion work with `catch` in C++? I.e., if you throw a `char*`, will it be caught when you catch `const char*`? This can not be handled easily with such a template, as we would need to catch both `CppException!(const(char)*)` and `CppException!(char*)`.

No, let's just stick to 1) please :p

Not only const(char) vs. char might be an issue because C's const doesn't match D's const exactly, but also char can be defined to be literally anything that can hold at least 8 bits.

http://msdn.microsoft.com/en-us/library/0d294k5z.aspx http://www.cplusplus.com/reference/climits/ http://en.wikipedia.org/wiki/C_data_types

I know this argument could be made about interfacing with C++ in general, but in case of throwing we do not replicate the structure of the C++ side in D as we would do with declarations of structs and classes, so the types would be thrown from C++ and end up "raw" in D.

I think this requires at least a D compiler flag to name the
C++ compiler eco system to emulate: e.g. MSVC++, ICC, DMC, GCC.
With that information you could then
catch(what_the_c_compiler_understands_by_a_const_unsigned_char_ptr)
or
catch(what_the_c_compiler_understands_by_a_const_signed_char_ptr)
NOT possible:
catch(what_the_c_compiler_understands_by_a_const_char_ptr),
because that would have been remapped by the C++ compiler to
either one of the former (I think).
The raw void* exception data for C char* may be presented inside
the catch block as byte*, ubyte*, ushort* or whatever is known
to match the C compiler specified on the command line.
(I hope my assumption about how C++ compilers mangle exception
 types is not too far off.)

-- 
Marco

September 12, 2014
On 12 Sep 2014 19:00, "via Digitalmars-d" <digitalmars-d@puremagic.com> wrote:
>
> On Friday, 12 September 2014 at 16:37:43 UTC, H. S. Teoh via
Digitalmars-d wrote:
>>
>> On Fri, Sep 12, 2014 at 06:19:54PM +0200, Marco Leise via Digitalmars-d
wrote:
>>>
>>> Am Fri, 12 Sep 2014 15:55:37 +0000
>>> schrieb "Sean Kelly" <sean@invisibleduck.org>:
>>>
>>> > On Friday, 12 September 2014 at 06:56:29 UTC, Jacob Carlborg > wrote:
>>> > > On 64bit Objective-C can catch C++ exceptions. But I don't > >
think you can do anything with the exception, i.e. it uses > > the following catch syntax:
>>> > >
>>> > > @catch(...) {}
>>> > >
>>> > > Would that be easier?
>>> > > I think the trick is setting up the stack frame in such a > way
that the C++ exception mechanism knows there's a catch > block available at all.  From there, we should be able to > use the standard interface-to-class method to call virtual > functions on the exception object, and hopefully the C++ > runtime will handle cleanup for us.
>>>
>>> What exception object?
>>>
>>> throw "bad things happened";
>>
>> [...]
>>
>>
>> Yeah, in C++, you can throw *anything*. Including ridiculous things like `throw NULL;` or `throw 3.14159;`. There's no method for that! What we might end up doing, might be to wrap the C++ exception in a D exception that contains a pointer to the C++ type along with whatever type info we can glean from the C++ runtime. We probably won't be able to do much more than that.
>
>
> How about
>
>     try {
>         my_cpp_func();
>     } catch(CppException!(const(char)*) e) {
>         writeln(e.payload.fromStringz());
>     }
>
> ?
>

I'd vote no.


September 12, 2014
On Friday, 12 September 2014 at 16:11:28 UTC, Marco Leise wrote:
> Am Fri, 12 Sep 2014 15:55:37 +0000
> schrieb "Sean Kelly" <sean@invisibleduck.org>:
>
>> On Friday, 12 September 2014 at 06:56:29 UTC, Jacob Carlborg wrote:
>> > On 64bit Objective-C can catch C++ exceptions. But I don't think you can do anything with the exception, i.e. it uses the following catch syntax:
>> >
>> > @catch(...) {}
>> >
>> > Would that be easier?
>> 
>> I think the trick is setting up the stack frame in such a way that the C++ exception mechanism knows there's a catch block available at all.  From there, we should be able to use the standard interface-to-class method to call virtual functions on the exception object, and hopefully the C++ runtime will handle cleanup for us.
>
> What exception object?
>
> throw "bad things happened";

Shouldn't matter.  It's just a callback taking a different
parameter type.  Though I think it would be a fair limitation to
say that D will only catch objects.
September 12, 2014
On Friday, 12 September 2014 at 17:57:41 UTC, Marc Schütz wrote:
>
> Btw, how does implicit conversion work with `catch` in C++? I.e., if you throw a `char*`, will it be caught when you catch `const char*`? This can not be handled easily with such a template, as we would need to catch both `CppException!(const(char)*)` and `CppException!(char*)`.

I'm hoping it's simply a matter of sticking the right data in a
lookup table and letting the C++ runtime figure out what the
proper match is for us.

D currently has a custom mechanism for throwing on non-Windows
platforms, but it may be worth switching to the established C++
approach, provided we can do so without losing anything (and this
is a big "if" given how we implicitly chain exceptions).