www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Error: functions cannot return static array float[4u][4u]

reply Spacen Jasset <spacen yahoo.co.uk> writes:
For this member function:

	float[4][4] toFloatArray4x4()
	{
		float f[4][4];
		return f;
	}

I get:
Error: functions cannot return static array float[4u][4u]

Is it the case that you can't return static arrays? Thinking about this 
it may make some sense. Should I therefore return a float[][] (which 
will always be a float [4]4]. I intend to assign it to a static 
float[4][4] in most cases.

Or rather, should I use an out/ref parameter like so:

toFloatArray4x4(ref float f[4][4])


I was also hoping to define a operator "overload" cast operator, but if 
I can't 'return' static arrays then this will not work.

I can return a struct from a function, why not a static array? I can 
sort of see why this might not work since D objects and types are more 
dynamic oriented than in C and C++ but it seems unnecessary to construct 
an object on the heap ( a float[][] ) just to return it and assign it to 
a static array.

Using:

Digital Mars D Compiler v1.026
Copyright (c) 1999-2008 by Digital Mars written by Walter Bright
Feb 21 2008
next sibling parent reply Jason House <jason.james.house gmail.com> writes:
Spacen Jasset wrote:

 For this member function:
 
 float[4][4] toFloatArray4x4()
 {
 float f[4][4];
 return f;
 }
This looks like doing the following in C++: C toC(){ C c; return c; } Which is an error (regardless of what the compiler says). c is allocated on the heap and is deallocated when the function exits. It may be that the same effect is happening here. I'm sure this kind of thing could get fixed in a similar way to how full closures were fixed...
Feb 21 2008
next sibling parent reply Jason House <jason.james.house gmail.com> writes:
Jason House wrote:

 Spacen Jasset wrote:
 
 For this member function:
 
 float[4][4] toFloatArray4x4()
 {
 float f[4][4];
 return f;
 }
This looks like doing the following in C++: C toC(){ C c; return c; } Which is an error (regardless of what the compiler says). c is allocated on the heap and is deallocated when the function exits. It may be that the same effect is happening here. I'm sure this kind of thing could get fixed in a similar way to how full closures were fixed...
I don't know why I said heap instead of stack, but I should have said stack.
Feb 21 2008
next sibling parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Jason House" <jason.james.house gmail.com> wrote in message 
news:fpl144$hco$2 digitalmars.com...

 I don't know why I said heap instead of stack, but I should have said 
 stack.
Fair enough :) but your snippet is still valid as the class/struct C is returned by value.
Feb 21 2008
parent Jason House <jason.james.house gmail.com> writes:
Jarrett Billingsley wrote:

 "Jason House" <jason.james.house gmail.com> wrote in message
 news:fpl144$hco$2 digitalmars.com...
 
 I don't know why I said heap instead of stack, but I should have said
 stack.
Fair enough :) but your snippet is still valid as the class/struct C is returned by value.
you're totally right. I had way too many errors in one post. Thankfully this is a D newsgroup and nobody will notice ;) I should have made the return type C&. This is common practice in C++ to avoid copying the class.
Feb 21 2008
prev sibling parent reply Spacen Jasset <spacen yahoo.co.uk> writes:
Jason House wrote:
 Jason House wrote:
 
 Spacen Jasset wrote:

 For this member function:

 float[4][4] toFloatArray4x4()
 {
 float f[4][4];
 return f;
 }
This looks like doing the following in C++: C toC(){ C c; return c; } Which is an error (regardless of what the compiler says). c is allocated on the heap and is deallocated when the function exits. It may be that the same effect is happening here. I'm sure this kind of thing could get fixed in a similar way to how full closures were fixed...
I don't know why I said heap instead of stack, but I should have said stack.
Hmm. That's legal in both C and C++ and works so long as 'C' isn't a pointer or array (otherwise you get a leak). I suppose then, that you could argue it's the same in D given that I was trying to return an array. On the other hand I observe that D arrays do not decompose into pointers like the do in C and C++ and so I guess I was expecting that returning an array would be possible since its more or less a proper 'object' unlike in C or C++. Returning a static array could then work in exactly the same way as returning a struct in D since they are fixed size and static in nature. Anyway, it seems it's not possible, and so I wonder what (in general) would be the way to go, return a float[][] object, or use a ( ref float[][] ) to pass the value back out, any suggestions?
Feb 21 2008
parent Spacen Jasset <spacen yahoo.co.uk> writes:
Spacen Jasset wrote:
 Jason House wrote:
 Jason House wrote:

 Spacen Jasset wrote:

 For this member function:

 float[4][4] toFloatArray4x4()
 {
 float f[4][4];
 return f;
 }
This looks like doing the following in C++: C toC(){ C c; return c; } Which is an error (regardless of what the compiler says). c is allocated on the heap and is deallocated when the function exits. It may be that the same effect is happening here. I'm sure this kind of thing could get fixed in a similar way to how full closures were fixed...
I don't know why I said heap instead of stack, but I should have said stack.
Hmm. That's legal in both C and C++ and works so long as 'C' isn't a pointer or array (otherwise you get a leak). I suppose then, that you could argue it's the same in D given that I was trying to return an array. On the other hand I observe that D arrays do not decompose into pointers like the do in C and C++ and so I guess I was expecting that returning an array would be possible since its more or less a proper 'object' unlike in C or C++. Returning a static array could then work in exactly the same way as returning a struct in D since they are fixed size and static in nature. Anyway, it seems it's not possible, and so I wonder what (in general) would be the way to go, return a float[][] object, or use a ( ref float[][] ) to pass the value back out, any suggestions?
I have just realized that arrays are symantically pass by reference always whereas structs are value types, and so that is why you cannot return a static array. Another solution to my problem is of course to use a Boxer for a float[16] and return that I guess.
Feb 21 2008
prev sibling parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Jason House" <jason.james.house gmail.com> wrote in message 
news:fpl0tk$hco$1 digitalmars.com...
 This looks like doing the following in C++:
 C toC(){
  C c;
  return c;
 }

 Which is an error (regardless of what the compiler says).  c is allocated 
 on
 the heap and is deallocated when the function exits.  It may be that the
 same effect is happening here.  I'm sure this kind of thing could get 
 fixed
 in a similar way to how full closures were fixed...
Not at all.. that declaration of 'c' has nothing to do with the heap, it's allocated on the stack, and when you return it, you're returning it by value. This is valid C++ code AFAIK. I think you're thinking of _this_: char* something() { char foo[10]; return foo; } Which _is_ illegal, because foo is allocated on the stack and you can't return arrays by value in C/C++. Which, coincidentally, is why you can't return statically-sized arrays in D, since they're supposed to be "C-like" in many ways.
Feb 21 2008
prev sibling next sibling parent reply Derek Parnell <derek nomail.afraid.org> writes:
On Thu, 21 Feb 2008 23:00:51 +0000, Spacen Jasset wrote:

 For this member function:
 
 	float[4][4] toFloatArray4x4()
 	{
 		float f[4][4];
 		return f;
 	}
 
 I get:
 Error: functions cannot return static array float[4u][4u]
On a related note, why can't D handle 'ref' and 'out' static arrays either? In other words, this below won't compile... void toFloatArray4x4(ref float[4][4] p) ... So what is the rationale for that? -- Derek (skype: derek.j.parnell) Melbourne, Australia 22/02/2008 10:48:36 AM
Feb 21 2008
parent reply Spacen Jasset <spacen yahoo.co.uk> writes:
Derek Parnell wrote:
 On Thu, 21 Feb 2008 23:00:51 +0000, Spacen Jasset wrote:
 
 For this member function:

 	float[4][4] toFloatArray4x4()
 	{
 		float f[4][4];
 		return f;
 	}

 I get:
 Error: functions cannot return static array float[4u][4u]
On a related note, why can't D handle 'ref' and 'out' static arrays either? In other words, this below won't compile... void toFloatArray4x4(ref float[4][4] p) ... So what is the rationale for that?
See my post above yours. arrays have pass by reference semantics unlike stucts, ints and other basic types.
Feb 21 2008
parent Derek Parnell <derek nomail.afraid.org> writes:
On Fri, 22 Feb 2008 00:25:44 +0000, Spacen Jasset wrote:

 Derek Parnell wrote:
 why can't D handle 'ref' and 'out' static arrays either?
 In other words, this below won't compile...
 
   void toFloatArray4x4(ref float[4][4] p) ...
 
 So what is the rationale for that?
 
... arrays have pass by reference semantics unlike stucts, ints and other basic types.
Agreed, but why is that a problem? The way I see it, the called function gets the address of the first element in the static array and the compiler knows the layout of the array "[4][4]' so why can't the called function use it like that? Currently, it seems like an artificial restraint. I can't see why this below should be hard to implement... // ------------- void toFloatArray4x4(ref float[4][4] p) { int n; n = 1; for (int i = 0; i < 4; i++) { for(int j = 0; j < 4; j++) { p[i][j] = n; n++; } } } void main() { float[4][4] r; toFloatArray4x4( r ); } // --------- -- Derek (skype: derek.j.parnell) Melbourne, Australia 22/02/2008 1:03:40 PM
Feb 21 2008
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"Spacen Jasset" wrote
 For this member function:

 float[4][4] toFloatArray4x4()
 {
 float f[4][4];
 return f;
 }

 I get:
 Error: functions cannot return static array float[4u][4u]

 Is it the case that you can't return static arrays? Thinking about this it 
 may make some sense. Should I therefore return a float[][] (which will 
 always be a float [4]4]. I intend to assign it to a static float[4][4] in 
 most cases.

 Or rather, should I use an out/ref parameter like so:

 toFloatArray4x4(ref float f[4][4])


 I was also hoping to define a operator "overload" cast operator, but if I 
 can't 'return' static arrays then this will not work.

 I can return a struct from a function, why not a static array? I can sort 
 of see why this might not work since D objects and types are more dynamic 
 oriented than in C and C++ but it seems unnecessary to construct an object 
 on the heap ( a float[][] ) just to return it and assign it to a static 
 array.
This is really an unnecessary limitation as far as I can tell. I think it's because static arrays are somehow treated as not fully-typed entities by the compiler. It also hurts in lazy IFTI functions, i.e.: writelazily(T)(bool dowrite, lazy T value) { if(dowrite) writefln(value); } writelazily(true, "hello"); // does not compile In your issue however, the following should work, and does not use the heap. struct FloatArray4x4 { float f[4][4]; } FloatArray4x4 toFloatArray4x4() {...} -Steve
Feb 21 2008
prev sibling parent reply Spacen Jasset <spacen yahoo.co.uk> writes:
The only way I've found to do this sort of thing without wrapping is via 
a pointer:


/* matrix is a static, or class member */
float[4][4] * toFloatArray4x4()
{
	return &matrix;
}


Used:

float v[4][4] = *m1.toFloatArray4x4();

I tried also concocting a system whereby I would return a float[][] 
object, but it doesn't seem easy to prepare such an object from a static 
array.


I feel that multi-dimensional array workings are a bit unintuitive.
Feb 25 2008
parent "Saaa" <empty needmail.com> writes:
Does Walter Bright recommend a way to return static arrays? 
Feb 25 2008