Steven Schveighoffer wrote: > On Tue, 08 Dec 2009 11:53:12 -0500, Bill Baxter <[email protected]> wrote: > >> On Tue, Dec 8, 2009 at 2:08 AM, Lutger <[email protected]> >> wrote: >>> Since a while some extern(C) functions which take arrays seem to be >>> broken. >>> Can anybody clarify /confirm how they should be declared? >>> >>> For example I stumbled upon this: >>> >>> import core.sys.posix.unistd, std.stdio; >>> >>> void main() >>> { >>> int[2] fd; >>> writeln( pipe(fd) ); // failes with errno == EFAULT >>> } >>> >>> In core.sys.posix.unistd, pipe is declared as: int pipe(int[2]); >>> >>> >>> This works though: >>> >>> extern (C) { int pipe(int*); } >>> >>> void main() >>> { >>> int[2] fd; >>> writeln( pipe(fd.ptr) ); >>> } >> >> (Assuming you're talking about D2 here...) >> A few releases ago fixed-size arrays changed to be pass-by-value. >> But I guess there's still some logic in there to interpret int[2] as >> int* when inside an extern(C) block. > > No it compiles *because* that logic is not there. It now thinks int[2] is > a pass-by-value entity. It links because you are using C linkage which > does not do name-mangling. I could define pipe as: > > extern (C) int pipe(char c, int x, float y); > > and it will still link :)
Interesting, I didn't realize that but it makes sense! > >> It does seem like there's a bug there, though. I think pipe(fd) in >> the first case should fail to compile because it's attempting to pass >> by value where a pointer is expected. > > The error is either: > > a) you now need to declare C functions that were declared in C taking an > array to taking a pointer, so core.sys.posix.unistd (and likely others) > needs to be fixed. > b) as you suggested, inside a C block, int[2] should be interpreted as int > *. > > I'd prefer a, because I don't care much about direct translation of C > headers :) If b is chosen as a solution, I'd also like to have the > compiler automatically pass the pointer when calling a C function. > > -Steve Thanks for the explanation, looks like there is some work to do in the binding department. This looks like a case where a piece of C code silently does something different in D.
