Passing ref T[n] to C

Jakob Ovrum jakobovrum at gmail.com
Mon Dec 9 08:11:38 PST 2013


On Monday, 9 December 2013 at 15:46:40 UTC, Mike Parker wrote:
> Given that on the C side, foo_t[3] parameters will degrade to 
> pointers, it's just as obvious to me to declare the function on 
> the D side like so:
>
> extern( C ) void take_foo( foo_t* );
>
> That means that one need pass foo.ptr when calling the 
> function, but it doesn't really bother me.

Do you mean `&foo`? While they both yield the same memory 
address, the type of the pointer is different. `foo.ptr` is typed 
as a pointer to the element type, while `&foo` is (completely 
regularly) typed as a pointer to the fixed-length array. i.e. 
`T*` vs `T[n]*` where T is the element type of the array.

> However, it was recently brought to my attention that the
> following actually works:
>
> extern( C ) void take_foo( ref foo_t );
>
> foo_t foo = [1, 2, 3];
> void take_foo( foo );
>
> I tested it with DMC and DMD and it actually worked fine. I was 
> expecting the length field to get in the way, but it didn't 
> seem to. I was able to print the values of the array just fine 
> on the C side.

Fixed-length arrays in D have no data-field for the length, 
because the length is always known at compile-time. ABI-wise, 
`int[3]` is always just 3 contiguous `int`s in memory. They are 
very unlike slices.

> My question is, can I rely on this? Is there a guarantee that a 
> ref static array parameter will be compatible with a C array 
> pointer on every platform and architecture? A voice in my head 
> is screaming NO at me in all caps and with multiple exclamation 
> points. But, if true, it would certainly simplify user code by 
> not having to remember to pass foo.ptr all the time. So I 
> thought I'd ask. I can't find anything regarding the 
> implementation details of ref parameters.

Upon consulting the specification[1], it looks like it's 
officially recommended to use `ref T[n]` for C's `T[n]`, and `T*` 
for C's `T[]`, in parameter lists.

[1] http://dlang.org/interfaceToC.html, "Passing D Array 
Arguments to C Functions"


More information about the Digitalmars-d-learn mailing list