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"