Translating C "static arrays" into D?
Atila Neves
atila.neves at gmail.com
Mon Feb 26 18:25:42 UTC 2018
On Monday, 26 February 2018 at 17:54:12 UTC, H. S. Teoh wrote:
> What's the correct translation of the following C declarations
> into D?
>
> typedef double[1] mytype;
This isn't valid C, but `typedef double mytype[1];` is.
>
> void someFunc(mytype x, mytype *y, mytype **z);
>
> struct SomeStruct {
> mytype x;
> mytype *y;
> mytype **z;
> }
>
> I need this to interface with an external C library.
> Currently, I just wrapped the above as-is inside an extern(C)
> block. But I suspect it may be wrong, because:
>
> 1) In C, declaring a function parameter of type double[1] is,
> IIRC, the same thing as declaring it as double*. But in D,
> double[1] passes one double by value as a static array. So
> there may be an API mismatch here.
Yes, a `double[1]` parameter in C and `double*` are the same
thing. However, that's not valid for the other two parameters (y
and z).
There's a common misconception in C that arrays and pointers are
the same thing - they're not. This comes about because of the
dubious C feature whereby arrays decay into pointers in function
calls. Somewhat related to this, a little known feature of C is
pointers to arrays. In your example, that's what y and z are.
They have funky syntax and look like function pointers, unless
they're obscured with a typedef as in your example.
You can pass a double array of any size to x, or a pointer to
double, but y and z are constrained to be pointers to arrays of
size 1. Exemplified:
typedef double mytype[1];
void func1(mytype x);
void func2(mytype* x);
int main() {
double arr1[1];
double arr2[2];
double* ptr;
func1(arr1); // fine
func1(arr2); // fine
func1(ptr); // fine
func2(&arr1); // fine
func2(&arr2); // oops - won't compile
}
>
> 2) In C, declaring a *variable* or struct field as double[1]
> has essentially the same semantics as D's static arrrays.
> Meaning that I cannot just change the declaration of mytype in
> order to get the correct behaviour of function parameters.
>
> 3) I'm getting a segfault at runtime of some C++ code into D,
> that calls
> the library via this C API, and I suspect it's probably due to
> (1).
The correct translation is:
extern(C) void someFunc(double* x, double[1]* y, double[1]** z);
Atila
More information about the Digitalmars-d
mailing list