Thread overview | ||||||
---|---|---|---|---|---|---|
|
February 26, 2018 Translating C "static arrays" into D? | ||||
---|---|---|---|---|
| ||||
What's the correct translation of the following C declarations into D?
typedef double[1] mytype;
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.
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).
T
--
Amateurs built the Ark; professionals built the Titanic.
|
February 26, 2018 Re: Translating C "static arrays" into D? | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | H. S. Teoh wrote:
> What's the correct translation of the following C declarations into D?
>
> typedef double[1] mytype;
>
> 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.
>
> 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).
>
>
> T
in C, arrays are *always* decaying to pointers. so
void foo (int x[2])
is the same as
void foo (int* x)
`[2]` is purely informational.
that is, in D it will be:
alias mytype = double*;
|
February 26, 2018 Re: Translating C "static arrays" into D? | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | 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 |
February 26, 2018 Re: Translating C "static arrays" into D? | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | On 2/26/18 12:54 PM, H. S. Teoh wrote:
> What's the correct translation of the following C declarations into D?
>
> typedef double[1] mytype;
>
> 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.
If you declare mytype as:
alias mytype = double[1];
Then you can use it pretty much anywhere. The only exception is when it's the exact type of a parameter. In that case, use ref:
extern(C) void someFunc(ref mytype x, mytype *y, mytype **z);
-Steve
|
Copyright © 1999-2021 by the D Language Foundation