Opinion from those in the know:

When extern(C) is used in druntime, my understanding is that the reason is twofold:

1. Because the compiler requires certain symbols for hooks.
2. To get around some requirements that "druntime knows better", such as purity for things like memory allocation that touch global state.

Is this true? There was a heated debate on a bug report [1] about extern(C) parameter definitions allowing D features, such as ref. Of course, C has no knowledge of ref, but it works like passing a pointer.

Now, if the above is true, I would propose that we migrate druntime to not use extern(C), but instead use pragma(mangle). The reason is simple -- extern(C) should behave like C. But there are some things that aren't the same. The one being debated heatedly was passing a fixed size array. An example:

C:
int pipe(int fd[2]);

Note that in C, static arrays are passed *by reference*. If we copy this to d:

extern(C) int pipe(int[2] fd);

This currently means pass fd *by value*. I think to do otherwise would be confusing. So the correct (IMO) thing to do is:

extern(C) int pipe(ref int[2] fd);

However, this doesn't sit right with many people who expect extern(C) to mean "call this function as C would call it".

But we have also as I said above, "hijacked" extern(C) to take advantage of the non-mangling features. In those cases, all those functions are not meant to be called from C, only from D. And they are all implemented in D. I don't want to limit those functions to only things that C supports.

Would it make sense to change to use pragma(mangle)? or is there some other reason why we use extern(C) in druntime? I'm asking the old veterans who may know some of the history, i.e. Walter, Sean, etc.

If we go this route, we can put more restrictions on actual extern(C) functions, and require the proper marking of functions. For example, passing a static array without ref should really be an error.

-Steve

[1] https://issues.dlang.org/show_bug.cgi?id=8887

Reply via email to