Jump to page: 1 2
Thread overview
Article: D Exceptions and C Callbacks
Aug 06, 2013
Mike Parker
Aug 06, 2013
QAston
Aug 07, 2013
Mike Parker
Aug 07, 2013
Johannes Pfau
Aug 07, 2013
Mike Parker
Aug 08, 2013
Marco Leise
Aug 08, 2013
Walter Bright
Aug 09, 2013
Marco Leise
Aug 10, 2013
Andrej Mitrovic
Aug 10, 2013
Walter Bright
Aug 10, 2013
Andrej Mitrovic
Aug 09, 2013
Rene Zwanenburg
Aug 09, 2013
Mike Parker
August 06, 2013
Shows how I like to deal with throwing exceptions from C callbacks in D. Target audience is beginner-level. Uses GLFW to demonstrate.

http://www.gamedev.net/page/resources/_/technical/general-programming/d-exceptions-and-c-callbacks-r3323
August 06, 2013
On Tuesday, 6 August 2013 at 15:05:22 UTC, Mike Parker wrote:
> Shows how I like to deal with throwing exceptions from C callbacks in D. Target audience is beginner-level. Uses GLFW to demonstrate.
>
> http://www.gamedev.net/page/resources/_/technical/general-programming/d-exceptions-and-c-callbacks-r3323

Good article, thanks.

There's one thing though. You say than relying on coder's discipline is error prone and I totally agree with that. But your sollution requires coder to remember to wrap those callbacks in try-catches. Maybe modifying glfwSetWindowCloseCallback and similar functions to only accept nothrow functions is a good idea?
August 07, 2013
On Tuesday, 6 August 2013 at 17:54:34 UTC, QAston wrote:

> There's one thing though. You say than relying on coder's discipline is error prone and I totally agree with that. But your sollution requires coder to remember to wrap those callbacks in try-catches.

Programming always requires a certain amount of discipline. Remembering to release resources when they are no longer needed, properly handling errors, being aware of the constraints of a particular API call. It's all differing degrees. I don't think it's too much trouble to wrap D function calls in try...catch blocks inside a C callback. It's a one-off thing for each callback and something that will likely be on the programmer's mind when a decision is made to implement such a solution. Properly handling arrays in C is an ongoing, full-time thing where it's easy to overlook a mistake now and again. So Id on't really see it as a problem.

> Maybe modifying glfwSetWindowCloseCallback and similar functions to only accept nothrow functions is a good idea?

I'm not sure what you mean. That's a C function, which means it doesn't have any concept of D's nothrow. And, actually, the callbacks should be declared as nothrow anyway. Like:

extern( C ) nothrow void function( GLFWwindow* ) glfwWindowCloseCallback;

Any exceptions thrown by functions called inside the callback must be handled, regardless, if you don't want to lose them.
August 07, 2013
Am Wed, 07 Aug 2013 03:33:28 +0200
schrieb "Mike Parker" <aldacron@gmail.com>:

> 
> > Maybe modifying glfwSetWindowCloseCallback and similar functions to only accept nothrow functions is a good idea?
> 
> I'm not sure what you mean. That's a C function, which means it doesn't have any concept of D's nothrow. And, actually, the callbacks should be declared as nothrow anyway. Like:

He meant declaring glfwSetWindowCloseCallback like this:
alias extern(C) nothrow void function() callback;
extern(C) void glfwSetWindowCloseCallback(callback cb);

http://dpaste.dzfl.pl/0f23146f
There's no difference in the generated code, but this way the compiler
will complain if you pass a non-nothrow function to
glfwSetWindowCloseCallback.
August 07, 2013
On Wednesday, 7 August 2013 at 07:10:21 UTC, Johannes Pfau wrote:
> Am Wed, 07 Aug 2013 03:33:28 +0200
> schrieb "Mike Parker" <aldacron@gmail.com>:
>
>> 
>> > Maybe modifying glfwSetWindowCloseCallback and similar functions to only accept nothrow functions is a good idea?
>> 
>> I'm not sure what you mean. That's a C function, which means it doesn't have any concept of D's nothrow. And, actually, the callbacks should be declared as nothrow anyway. Like:
>
> He meant declaring glfwSetWindowCloseCallback like this:
> alias extern(C) nothrow void function() callback;
> extern(C) void glfwSetWindowCloseCallback(callback cb);
>
> http://dpaste.dzfl.pl/0f23146f
> There's no difference in the generated code, but this way the compiler
> will complain if you pass a non-nothrow function to
> glfwSetWindowCloseCallback.

Yeah, I see. I misunderstood. I agree that the callbacks should be declared as nothrow. In Derelict, all the C function pointers are declared as such. Apparently, I overlooked adding it to the callbacks.
August 08, 2013
Am Wed, 07 Aug 2013 12:08:44 +0200
schrieb "Mike Parker" <aldacron@gmail.com>:

> On Wednesday, 7 August 2013 at 07:10:21 UTC, Johannes Pfau wrote:
> > Am Wed, 07 Aug 2013 03:33:28 +0200
> > schrieb "Mike Parker" <aldacron@gmail.com>:
> >
> >> 
> >> > Maybe modifying glfwSetWindowCloseCallback and similar functions to only accept nothrow functions is a good idea?
> >> 
> >> I'm not sure what you mean. That's a C function, which means it doesn't have any concept of D's nothrow. And, actually, the callbacks should be declared as nothrow anyway. Like:
> >
> > He meant declaring glfwSetWindowCloseCallback like this:
> > alias extern(C) nothrow void function() callback;
> > extern(C) void glfwSetWindowCloseCallback(callback cb);
> >
> > http://dpaste.dzfl.pl/0f23146f
> > There's no difference in the generated code, but this way the
> > compiler
> > will complain if you pass a non-nothrow function to
> > glfwSetWindowCloseCallback.
> 
> Yeah, I see. I misunderstood. I agree that the callbacks should be declared as nothrow. In Derelict, all the C function pointers are declared as such. Apparently, I overlooked adding it to the callbacks.

I recently proposed using nothrow in GtkD as well. This article was kind of a coincidence now. Yes, it is a real issue with binding to C code unfortunately. Especially on amd64 with GCC compiled stuff since it omits the stack frame that DMD requires to unwind the stack resulting in immediate crashes (druntime HLTs the execution) as soon as you throw an exception from a callback.

-- 
Marco

August 08, 2013
On 8/8/2013 6:48 AM, Marco Leise wrote:
> I recently proposed using nothrow in GtkD as well. This
> article was kind of a coincidence now. Yes, it is a real issue
> with binding to C code unfortunately. Especially on amd64 with
> GCC compiled stuff since it omits the stack frame that DMD
> requires to unwind the stack resulting in immediate crashes
> (druntime HLTs the execution) as soon as you throw an
> exception from a callback.


I agree that C callbacks called from C code should be nothrow.

At a minimum, the C code that calls the callback is not going to be expecting an exit via exception, and so may leave things in an indeterminate state.
August 09, 2013
Am Thu, 08 Aug 2013 11:33:28 -0700
schrieb Walter Bright <newshound2@digitalmars.com>:

> On 8/8/2013 6:48 AM, Marco Leise wrote:
> > I recently proposed using nothrow in GtkD as well. This article was kind of a coincidence now. Yes, it is a real issue with binding to C code unfortunately. Especially on amd64 with GCC compiled stuff since it omits the stack frame that DMD requires to unwind the stack resulting in immediate crashes (druntime HLTs the execution) as soon as you throw an exception from a callback.
> 
> 
> I agree that C callbacks called from C code should be nothrow.
> 
> At a minimum, the C code that calls the callback is not going to be expecting an exit via exception, and so may leave things in an indeterminate state.

Just for completeness: In a recent discussion on IRC I learned that vendor specific attributes exist for C compilers to mark functions as "ok to use with exceptions".

-- 
Marco

August 09, 2013
On Tuesday, 6 August 2013 at 15:05:22 UTC, Mike Parker wrote:
> Shows how I like to deal with throwing exceptions from C callbacks in D. Target audience is beginner-level. Uses GLFW to demonstrate.
>
> http://www.gamedev.net/page/resources/_/technical/general-programming/d-exceptions-and-c-callbacks-r3323

Nice article. A few minor corrections:

- In your second code sample, the D translation of the C code, the line
    glfwSetWindowCloseCallback( &onWindowClose );
  should read either
    glfwSetWindowCloseCallback( win, &onWindowClose );
  or
    win.glfwSetWindowCloseCallback( &onWindowClose );
  Maybe point out both are possible, but perhaps this is out of the scope of the article.

- When explaining the difference between D Throwable, Exception, and Error, you write:
    The latter is analagous to Java's RuntimeException in that
    it is not intended to be caught. It should be thrown to
    indicate an unrecoverable error in the program.
  Java uses Error for unrecoverable errors too. RuntimeExceptions are recoverable and meant to be catched. It would be more accurate to say D lacks Java's checked exceptions, D exceptions are like Java's RuntimeExceptions, and D Errors are like Java Errors.
August 09, 2013
On Friday, 9 August 2013 at 14:08:48 UTC, Rene Zwanenburg wrote:

>
> - In your second code sample, the D translation of the C code, the line
>     glfwSetWindowCloseCallback( &onWindowClose );
>   should read either
>     glfwSetWindowCloseCallback( win, &onWindowClose );
>   or
>     win.glfwSetWindowCloseCallback( &onWindowClose );

Thanks! That was an oversight. I've corrected it.

>
> - When explaining the difference between D Throwable, Exception, and Error, you write:
>     The latter is analagous to Java's RuntimeException in that
>     it is not intended to be caught. It should be thrown to
>     indicate an unrecoverable error in the program.
>   Java uses Error for unrecoverable errors too. RuntimeExceptions are recoverable and meant to be catched. It would be more accurate to say D lacks Java's checked exceptions, D exceptions are like Java's RuntimeExceptions, and D Errors are like Java Errors.

I just removed the reference to Java entirely. Thanks for pointing that out. I've had it in my head for years that RuntimeException was for unrecoverable errors.
« First   ‹ Prev
1 2