On Wed, Feb 21, 2018 at 11:16:44PM -0500, Nick Sabalausky (Abscissa) via Digitalmars-d-learn wrote: > Are there any tutorials or articles out there for "getting started > with converting a C++ codebase to D one module at a time?" Or at the > very least: tips, tricks, lessions learned, from those who have come > before.
Here's a really nasty thing that I just came across today (cf. other thread as well), in translating C++ code that calls an external library via a C API: // C (called from original C++ code): typedef double mytype[1]; struct blah { mytype x; } void foo(mytype x); void bar(struct blah b); A naïve translation to D would be: // D (incorrect) alias mytype = double[1]; struct blah { mytype x; } void foo(mytype x); // Uh oh void bar(struct blah b); The problem is that in C, a function parameter declared as double[1] is actually the same as double* because of C's infamous array -> pointer degradation. So the parameter of foo should actually be declared as double*, not as double[1] (via the `mytype` alias). However, simply changing the definition of `mytype` to `double*` leads to another problem: the definition of struct blah will be wrong, because in C, a struct field declared as double[n] is actually equivalent to a D static array, i.e., it occupies the space of n doubles. Changing that to double* makes the D declaration of the struct incorrect. Furthermore, calling foo from D now requires explicitly writing `&x` instead of merely `x`. The solution I eventually settled on is to adopt the convention that whenever a C "static array" appears as a function parameter, declare it as `ref`. So: // D (correct) alias mytype = double[1]; struct blah { mytype x; } void foo(ref mytype x); // N.B.: add `ref` here void bar(struct blah b); This allows correct matching to the C API without requiring inserting `&`s everywhere. T -- What's an anagram of "BANACH-TARSKI"? BANACH-TARSKI BANACH-TARSKI.