June 20, 2014
https://issues.dlang.org/show_bug.cgi?id=12959

          Issue ID: 12959
           Summary: nothrow should be required for extern(C) functions
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P1
         Component: DMD
          Assignee: nobody@puremagic.com
          Reporter: code@dawg.eu

This issues pops up regularly and boils down to some simple insights.

D's exception handling mechanism can't unwind C function stacks because it always requires a frame pointer. This means that in many cases throwing an exception in a D function that was called from C will crash your program. Therefor it is safer to require nothrow for D functions which are declared as extern(C).

A C function cannot throw a D exception, so they should always be declared as nothrow.

D callbacks passed to C functions have the same issues as D function called directly from C, so any extern(C) callback should be declared as nothrow.

Sometimes extern(C) is used to bind two D functions without having to import
any modules. While this is a legitimate use-case and exception handling works
here, extern(D) bindings can be used instead (see [1]).

The conclusion of the above reasons is to always require nothrow when declaring an extern(C) function.


[1]:
The main reason why extern(C) is preferred over extern(D) is the more difficult
mangling. This could be simplified with the help of
http://dlang.org/phobos/core_demangle.html#.mangleFunc and a template to
declare extern(D) functions. This solution is also more type safe than
extern(C) bindings.

    alias _d_monitor_create = externDFunc!("rt.monitor._create", void
function(Object));

--