Thread overview
Re: Translating C "static arrays" into D?
Feb 26, 2018
H. S. Teoh
Feb 26, 2018
H. S. Teoh
Feb 26, 2018
ketmar
February 26, 2018
On Mon, Feb 26, 2018 at 09:54:12AM -0800, H. S. Teoh via Digitalmars-d wrote:
> What's the correct translation of the following C declarations into D?
> 
> 	typedef double[1] mytype;

Sorry, typo, should be:

 	typedef double mytype[1];


> 	void someFunc(mytype x, mytype *y, mytype **z);
> 
> 	struct SomeStruct {
> 		mytype x;
> 		mytype *y;
> 		mytype **z;
> 	}
[...]


T

-- 
Real men don't take backups. They put their source on a public FTP-server and let the world mirror it. -- Linus Torvalds
February 26, 2018
On Mon, Feb 26, 2018 at 08:07:11PM +0200, ketmar via Digitalmars-d wrote: [...]
> 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*;

Actually, that doesn't work, because in the struct declaration it will be wrong:

	// C
	struct S {
		double[5] x; // actually occupies the space of 5 doubles
	}

	// D
	struct S {
		double* x; // occupies the space of 1 pointer (wrong)
	}

Furthermore, declaring it as `double*` breaks existing code ported from C:

	// Original C code:
	void foo(mytype x);
	mytype z;
	foo(z);

	// D code:
	void foo(double* x);	// OK
	mytype z;		// NG
	foo(z);			// NG: passes uninitialized pointer

	// alternatively:
	double[1] z;
	foo(z);			// NG: need to insert `&` to compile

Eventually I figured out a (hackish) solution to make it work without silently breaking transliterated C code: declare all function parameters that take `mytype` as ref.  This causes the D compiler to simulate the array -> pointer degradation semantics but still retain "static array" semantics in structs and variable declarations, without requiring a change in syntax.


T

-- 
Food and laptops don't mix.
February 26, 2018
H. S. Teoh wrote:

> On Mon, Feb 26, 2018 at 08:07:11PM +0200, ketmar via Digitalmars-d wrote:
> [...]
>> 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*;
>
> Actually, that doesn't work, because in the struct declaration it will
> be wrong:
>
> 	// C
> 	struct S {
> 		double[5] x; // actually occupies the space of 5 doubles
> 	}
>
> 	// D
> 	struct S {
> 		double* x; // occupies the space of 1 pointer (wrong)
> 	}

yeah, sorry. somehow i completely missed structs.