How does D compare to Go when it comes to C interop?

Chris Wright via Digitalmars-d digitalmars-d at puremagic.com
Thu Dec 10 08:37:16 PST 2015


On Thu, 10 Dec 2015 13:33:07 +0000, Pradeep Gowda wrote:

> I read this post about the difficulties of using go/cgo to interface
> with C code:
> http://www.cockroachlabs.com/blog/the-cost-and-complexity-of-cgo/
> 
> How does D do in comparison? specifically in regards to:
> 
> 1. Call overhead (CGo is 100 times slower than native Go fn call)

C calls use the C calling convention. That's the only runtime difference. 
The C calling convention is fast, of course, and D's is comparable.

>From what you're saying about Go, it sounds like someone implemented the 
C calling convention at runtime. A few years ago (circa 2008, I think?), 
I implemented something like this in D (call a function with a series of 
boxed values, specifically). It was about 150 times slower than just 
calling the function directly in my brief tests.

You can use packed C structs in D, which is one thing that cgo doesn't 
allow.

> 2. Memory management. (I guess D is not immune from having to manage
> memory for the C functions it calls.. but is there a difference in
> approach? is it safer in D?)

For C interop?

You can allocate memory in D and pass it to C functions. This requires 
some caution. If you send a pointer to a C function that allocates memory 
on the heap and stores that pointer in that memory, the GC doesn't know 
about that.

If you are writing the code on both sides, you can forbid that pattern. 
If you are uncertain, you can hold a reference to anything you pass to C 
code until you know it's safe to discard it.

Finally, if the C code takes ownership of the pointer (and expects to be 
able to realloc / free it), you must use malloc. realloc and free may 
well crash if you try to realloc pointers they don't know about.

If you're using D and not calling C functions, you can easily write 
memory-safe code, and there's a garbage collector to boot.

> 3. Cgorountes != goroutines (This one may not apply for D)

On the other hand, coroutines are coroutines, and D has a coroutine 
implementation (core.thread.Fiber).

In Go, all IO is tightly integrated with the coroutine scheduler. The 
reason it requires caution to use C from Go is that, if you perform a 
blocking operation, your entire program will block, unlike what happens 
if you use Go IO functions.

If you are using vibe.d, you have a similar IO model and need similar 
caution. That's about it, I think. Since you can call D from C/C++, you 
can implement coroutine-aware code in C that will yield at the 
appropriate places.

> 4. Static builds (how easy/straight-forward is this in D?)

DUB, the D build and dependency tool, produces static libraries by 
default.



More information about the Digitalmars-d mailing list