Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extern(C) functions should be nothrow @nogc #36

Closed
mleise opened this issue Sep 17, 2016 · 5 comments
Closed

Extern(C) functions should be nothrow @nogc #36

mleise opened this issue Sep 17, 2016 · 5 comments

Comments

@mleise
Copy link

mleise commented Sep 17, 2016

If they don't call D code internally, C functions should be marked extern(C) nothrow @nogc { … }.

@rcorre
Copy link
Contributor

rcorre commented Sep 18, 2016

call D code internally

Would this include any C function that takes a function pointer, as it could be passed a D function (marked with extern(C)) that allocates or throws?

@rikkimax
Copy link
Contributor

@rcorre you can mark functions/delegates as nothrow.

alias myFunc = extern(C) void function() nothrow;

Any function being passed to or is a c function declaration should really be nothrow @system @nogc. After all c code won't be calling our GC, throwing our exceptions and is most definitely not safe.

@rcorre
Copy link
Contributor

rcorre commented Sep 18, 2016

So marking a such a C function as @nogc nothrow would prevent passing any function that isn't also @nogc nothrow, which is generally a 'good thing'? Would the passed function have to be explicitly marked as such or can it be implied (i.e. could it break existing code)?

@rikkimax
Copy link
Contributor

There are two separate cases going on here:

extern(C)
void cFunc() nothrow @system @nogc;
alias ACFunc = extern(C) void function() nothrow @system @nogc;

extern(C)
void cFunc(ACFunc arg)  nothrow @system @nogc;

So in the first case is the same as defining a function in C and exporting it for access via shared library loading, but it won't accept any arguments that are functions.

In the second case we pass in a function to a C function. Keep in mind both the C function as well as the argument must be declared as being extern(C) as well as nothrow @system @nogc.

After all, our exceptions and GC collecting won't work from within C code and good chance it'll end in a segfault.

The only attribute that can be not included in this is @nogc as long as you know what the C code is doing and in most cases its fine.

@mleise
Copy link
Author

mleise commented Sep 18, 2016

I've experienced such segfaults first hand some time ago with GtkD. My D code threw an exception inside C code and druntime tried to unwind the stack. To do so it looks at the frame pointer register, but all my C libraries are compiled without explicit frame pointer. So druntime misinterpreted the register for a stack frame and crashed when dereferencing it.
This request here doesn't have to do with that though. I'd just like to use Allegro5 in code marked @nogc and thought I should put a "reminder" somewhere.

rcorre added a commit to rcorre/DAllegro5 that referenced this issue Sep 27, 2016
Resolves SiegeLord#36: Extern(C) functions should be `nothrow @nogc`
rcorre added a commit to rcorre/DAllegro5 that referenced this issue Oct 1, 2016
Resolves SiegeLord#36: Extern(C) functions should be `nothrow @nogc`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants