Thread overview | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
October 24, 2012 Passing static arrays to C | ||||
---|---|---|---|---|
| ||||
Hey everybody. How are you supposed to pass static arrays to C functions? I'm asking because I'm getting conflicting info from how DMD works and on IRC. The below example prints: test1 0x7fff857c1db0 test2 0x7fff857c1db0 test3 (nil) test4 0x7fff857c1db0 D: void main() { float[3] arr; test1(arr); test2(&arr[0]); test3(0, arr); test4(0, &arr[0]); } extern(C): void test1(float[3] arr); void test2(float *arr); void test3(int, float[3] arr); void test4(int, float *arr); C: #include <stdio.h> void test1(float arr[3]) { printf("test1 %p\n", &arr[0]); } void test2(float arr[3]) { printf("test2 %p\n", &arr[0]); } void test3(int anything, float arr[3]) { printf("test3 %p\n", &arr[0]); } void test4(int anything, float arr[3]) { printf("test4 %p\n", &arr[0]); } Comments please. Cheers, Jakob. |
October 24, 2012 Re: Passing static arrays to C | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jakob Bornecrantz | On 2012-10-24 09:54, Jakob Bornecrantz wrote: > Hey everybody. > > How are you supposed to pass static arrays to C functions? I'm asking > because I'm getting conflicting info from how DMD works and on IRC. > > The below example prints: > test1 0x7fff857c1db0 > test2 0x7fff857c1db0 > test3 (nil) > test4 0x7fff857c1db0 > > > D: > void main() > { > float[3] arr; > test1(arr); > test2(&arr[0]); > test3(0, arr); > test4(0, &arr[0]); > } > > extern(C): > void test1(float[3] arr); > void test2(float *arr); > void test3(int, float[3] arr); > void test4(int, float *arr); > > > C: > #include <stdio.h> > > void test1(float arr[3]) { printf("test1 %p\n", &arr[0]); } > void test2(float arr[3]) { printf("test2 %p\n", &arr[0]); } > void test3(int anything, float arr[3]) { printf("test3 %p\n", &arr[0]); } > void test4(int anything, float arr[3]) { printf("test4 %p\n", &arr[0]); } That seems weird. Since static arrays are passed by value in D you need to send a reference: extern (C) void test1(ref float[3] arr); float[3] arr; test1(arr); BTW, do not ever use "&arr[0]", use "arr.ptr" instead to get the pointer of the array. http://dlang.org/interfaceToC.html Search for "Passing D Array Arguments to C Functions". -- /Jacob Carlborg |
October 24, 2012 Re: Passing static arrays to C | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jakob Bornecrantz | On 10/24/2012 12:54 AM, Jakob Bornecrantz wrote: > How are you supposed to pass static arrays to C functions? C accepts static arrays as pointers, so T[n] in D would be C prototyped as T*. Pass a pointer to the first element. |
October 24, 2012 Re: Passing static arrays to C | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On Wednesday, 24 October 2012 at 09:03:25 UTC, Jacob Carlborg wrote: > On 2012-10-24 09:54, Jakob Bornecrantz wrote: >> Hey everybody. >> >> How are you supposed to pass static arrays to C functions? I'm asking >> because I'm getting conflicting info from how DMD works and on IRC. >> >> The below example prints: >> test1 0x7fff857c1db0 >> test2 0x7fff857c1db0 >> test3 (nil) >> test4 0x7fff857c1db0 >> >> >> D: >> void main() >> { >> float[3] arr; >> test1(arr); >> test2(&arr[0]); >> test3(0, arr); >> test4(0, &arr[0]); >> } >> >> extern(C): >> void test1(float[3] arr); >> void test2(float *arr); >> void test3(int, float[3] arr); >> void test4(int, float *arr); >> >> >> C: >> #include <stdio.h> >> >> void test1(float arr[3]) { printf("test1 %p\n", &arr[0]); } >> void test2(float arr[3]) { printf("test2 %p\n", &arr[0]); } >> void test3(int anything, float arr[3]) { printf("test3 %p\n", &arr[0]); } >> void test4(int anything, float arr[3]) { printf("test4 %p\n", &arr[0]); } > > That seems weird. Since static arrays are passed by value in D you need to send a reference: Yeah I'm wondering if this isn't a bug. > > extern (C) void test1(ref float[3] arr); > > float[3] arr; > test1(arr); > > BTW, do not ever use "&arr[0]", use "arr.ptr" instead to get the pointer of the array. Right you are, thats what you get when mixing C and D code. > > http://dlang.org/interfaceToC.html > > Search for "Passing D Array Arguments to C Functions". Thanks for the info. Cheers, Jakob. |
October 24, 2012 Re: Passing static arrays to C | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Wednesday, 24 October 2012 at 09:16:30 UTC, Walter Bright wrote:
> C accepts static arrays as pointers, so T[n] in D would be C prototyped as T*.
>
> Pass a pointer to the first element.
In GCC (or any c compiler) isn't it possible in optimizing to copy the static array to the stack (say 8 bytes or less as a guess)? Course this assumes the static size is set as part of the function signature too...
It makes sense for it to work both ways (in their own way); But then more bugs can lie in wait as well.
|
October 24, 2012 Re: Passing static arrays to C | ||||
---|---|---|---|---|
| ||||
Posted in reply to Era Scarecrow | On 24-10-2012 12:00, Era Scarecrow wrote: > On Wednesday, 24 October 2012 at 09:16:30 UTC, Walter Bright wrote: >> C accepts static arrays as pointers, so T[n] in D would be C >> prototyped as T*. >> >> Pass a pointer to the first element. > > In GCC (or any c compiler) isn't it possible in optimizing to copy the > static array to the stack (say 8 bytes or less as a guess)? Course this > assumes the static size is set as part of the function signature too... > > It makes sense for it to work both ways (in their own way); But then > more bugs can lie in wait as well. Passing static arrays by reference to the first element is part of the calling convention/ABI. If the C compiler generated code that doesn't work this way, the C compiler has a bug. -- Alex Rønne Petersen alex@lycus.org http://lycus.org |
October 24, 2012 Re: Passing static arrays to C | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jakob Bornecrantz | On 10/24/2012 2:55 AM, Jakob Bornecrantz wrote:
> On Wednesday, 24 October 2012 at 09:03:25 UTC, Jacob Carlborg wrote:
>> On 2012-10-24 09:54, Jakob Bornecrantz wrote:
>>> Hey everybody.
>>>
>>> How are you supposed to pass static arrays to C functions? I'm asking
>>> because I'm getting conflicting info from how DMD works and on IRC.
>>>
>>> The below example prints:
>>> test1 0x7fff857c1db0
>>> test2 0x7fff857c1db0
>>> test3 (nil)
>>> test4 0x7fff857c1db0
>>>
>>>
>>> D:
>>> void main()
>>> {
>>> float[3] arr;
>>> test1(arr);
>>> test2(&arr[0]);
>>> test3(0, arr);
>>> test4(0, &arr[0]);
>>> }
>>>
>>> extern(C):
>>> void test1(float[3] arr);
>>> void test2(float *arr);
>>> void test3(int, float[3] arr);
>>> void test4(int, float *arr);
>>>
>>>
>>> C:
>>> #include <stdio.h>
>>>
>>> void test1(float arr[3]) { printf("test1 %p\n", &arr[0]); }
>>> void test2(float arr[3]) { printf("test2 %p\n", &arr[0]); }
>>> void test3(int anything, float arr[3]) { printf("test3 %p\n", &arr[0]); }
>>> void test4(int anything, float arr[3]) { printf("test4 %p\n", &arr[0]); }
>>
>> That seems weird. Since static arrays are passed by value in D you need to
>> send a reference:
>
> Yeah I'm wondering if this isn't a bug.
In D, static arrays are passed by value, in C by pointer. Hence, you have a mismatch between the C and D prototypes of test1, and you'll get garbage results.
|
October 24, 2012 Re: Passing static arrays to C | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | Walter Bright:
> In D, static arrays are passed by value, in C by pointer. Hence, you have a mismatch between the C and D prototypes of test1, and you'll get garbage results.
Isn't it possible to help the programmer avoid some similar mistakes with some warnings or errors?
I think the extern(C) annotation, plus the function signatures, give the D compiler all the info it needs.
Bye,
bearophile
|
October 24, 2012 Re: Passing static arrays to C | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On 10/24/12, bearophile <bearophileHUGS@lycos.com> wrote:
> Isn't it possible to help the programmer avoid some similar mistakes with some warnings or errors?
>
> I think the extern(C) annotation, plus the function signatures, give the D compiler all the info it needs.
Agreed. File to bugzilla unless Walter disagrees?
|
October 24, 2012 Re: Passing static arrays to C | ||||
---|---|---|---|---|
| ||||
On 10/24/12, Andrej Mitrovic <andrej.mitrovich@gmail.com> wrote:
> Agreed. File to bugzilla unless Walter disagrees?
Also, what should the error message look like? I've got a pull in works fwiw.
|
Copyright © 1999-2021 by the D Language Foundation