static arrays in C functions
Steven Schveighoffer
schveiguy at yahoo.com
Tue Dec 8 09:36:28 PST 2009
On Tue, 08 Dec 2009 11:53:12 -0500, Bill Baxter <wbaxter at gmail.com> wrote:
> On Tue, Dec 8, 2009 at 2:08 AM, Lutger <lutger.blijdestijn at gmail.com>
> 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 :)
> 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
More information about the Digitalmars-d-learn
mailing list