September 12, 2014 Re: C++/D interface: exceptions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Iain Buclaw | 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 Re: C++/D interface: exceptions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | 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 Re: C++/D interface: exceptions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | 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 Re: C++/D interface: exceptions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | 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 Re: C++/D interface: exceptions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marco Leise | 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 Re: C++/D interface: exceptions | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | 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 Re: C++/D interface: exceptions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marc Schütz | 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 Re: C++/D interface: exceptions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marc Schütz Attachments:
| 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 Re: C++/D interface: exceptions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marco Leise | 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 Re: C++/D interface: exceptions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marc Schütz | 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).
|
Copyright © 1999-2021 by the D Language Foundation