Bug 12959 – nothrow should be required for extern(C) functions

Status
RESOLVED
Resolution
WONTFIX
Severity
enhancement
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-06-20T15:26:48Z
Last change time
2017-10-26T06:54:05Z
Assigned to
No Owner
Creator
Martin Nowak

Comments

Comment #0 by code — 2014-06-20T15:26:48Z
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));
Comment #1 by danny.milo — 2014-11-27T17:47:51Z
I agree. C can't throw exceptions so why have extern(C) ever be "not nothrow"? What about making extern(C) imply nothrow automatically? That would be the nicest solution, I think (most people know that C can't throw exceptions, so no confusion there).
Comment #2 by bugzilla — 2017-10-26T06:54:05Z
A D function that calls a C function that calls a D function that throws should work, even if the current implementation doesn't. So, I don't think it should be a requirement for extern(C) functions to be nothrow.