www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - convert static arrays to dynamic arrays and return, have wrong data.

reply "AlanThinker" <alanthinker 126.com> writes:
It seems that, D's array is strange,
It can implicit convert static arrays to dynamic arrays no error 
and no warning.
But when I return the converted arrays out the function.
Outside function will get some wrong data.

It may very easily cause some bug because no error when convert 
static arrays to dynamic arrays.

CODE:

import std.stdio;

void main()
{
	auto a1 = test11();
	auto a2 = test22();
	assert(a1==a2);
	writeln(a1);
	writeln(a2);
	getchar();
}

int[3] test1()
{
	int[3] arr;
	arr[0]=1;
	arr[1]=2;
	arr[2]=3;
	return arr;
}

int[] test11()
{
	return test1();
}

int[3] test2()
{
	int[3] arr;
	arr[0]=1;
	arr[1]=2;
	arr[2]=3;
	return arr;
}

int[] test22()
{
	return test2();
}
Nov 09 2014
next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
AlanThinker:

 It seems that, D's array is strange,
 It can implicit convert static arrays to dynamic arrays no 
 error and no warning.
 But when I return the converted arrays out the function.
 Outside function will get some wrong data.

 It may very easily cause some bug because no error when convert 
 static arrays to dynamic arrays.
Yeah, what do you suggest to change in the language to avoid this problem? Bye, bearophile
Nov 09 2014
next sibling parent reply "AlanThinker" <alanthinker 126.com> writes:
Is it possible to raise error when implicit convert static arrays 
to dynamic arrays?
Because there are really different.


On Sunday, 9 November 2014 at 10:04:16 UTC, bearophile wrote:
 AlanThinker:

 It seems that, D's array is strange,
 It can implicit convert static arrays to dynamic arrays no 
 error and no warning.
 But when I return the converted arrays out the function.
 Outside function will get some wrong data.

 It may very easily cause some bug because no error when 
 convert static arrays to dynamic arrays.
Yeah, what do you suggest to change in the language to avoid this problem? Bye, bearophile
Nov 09 2014
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
AlanThinker:

 Is it possible to raise error when implicit convert static 
 arrays to dynamic arrays?
 Because there are really different.
To do this you need a sound tracking of memory areas. I think this is a "must have" for D, but so far D designers think otherwise. If you just disallow that kind of operations indiscriminately, you reduce a lot the usefulness of D (because fixed size => dynamic slice array is a conversion useful in many cases) and probably force the introduction of many casts, and I don't know if this will increase the overall safety of the D code. Bye, bearophile
Nov 09 2014
next sibling parent reply "novice2" <sorry noem.ail> writes:
BTW, adding .dup resolve error:

int[] test11()
{
   return test1().dup;
}

int[] test22()
{
   return test2().dup;
}
Nov 09 2014
next sibling parent reply "novice2" <sorry noem.ail> writes:
int[3] test1()
{
   int[3] arr;
   ...
}

disasm shows:
- arr created on stack
- arr address returned
- stack changed
- data lost.
Nov 09 2014
parent ketmar via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Sun, 09 Nov 2014 12:46:28 +0000
novice2 via Digitalmars-d <digitalmars-d puremagic.com> wrote:

 int[3] test1()
 {
    int[3] arr;
    ...
 }
=20
 disasm shows:
 - arr created on stack
 - arr address returned
 - stack changed
 - data lost.
hm. what i see in disasm is: array is created on the *caller* stack. then address of that array passed to `test1()` as hidden argument, so `test1()` actually returns nothing at all, it just changes that passed array.
Nov 09 2014
prev sibling parent "AlanThinker" <alanthinker 126.com> writes:
 BTW, adding .dup resolve error:
BTW, adding .dup resolve error, but i mean it easy to make mistake because no compile error when implicit convert.
Nov 09 2014
prev sibling parent reply Nick Treleaven <ntrel-pub mybtinternet.com> writes:
On 09/11/2014 10:34, bearophile wrote:
 If you just disallow that kind of operations indiscriminately, you
 reduce a lot the usefulness of D (because fixed size => dynamic slice
 array is a conversion useful in many cases) and probably force the
 introduction of many casts, and I don't know if this will increase the
 overall safety of the D code.
Seeing as the 'scope' attribute doesn't seem to be happening any time soon, shouldn't the compiler reject static array slicing in safe code? The user is then forced to think about the operation, and put the code in a trusted delegate if they think it is actually safe. <grumble> It would help a bit if we had trusted blocks instead of having to call a trusted delegate inline (which is non-obvious). The status quo encourages people to just mark whole functions as trusted, skipping much otherwise acceptable safety enforcement. </grumble>
Nov 12 2014
parent reply Nick Treleaven <ntrel-pub mybtinternet.com> writes:
On 12/11/2014 15:36, Nick Treleaven wrote:
 Seeing as the 'scope' attribute doesn't seem to be happening any time
 soon, shouldn't the compiler reject static array slicing in  safe code?
 The user is then forced to think about the operation, and put the code
 in a  trusted delegate if they think it is actually safe.
This is: https://issues.dlang.org/show_bug.cgi?id=8838 Apparently it's a bit tricky to implement ATM. yebblies:
 This is not very easy, because the compiler lowers all static array
 assignment to slice assignment, making _every_ static array assignment
 unsafe.  That needs to be fixed first, and requires extensive changes 
 in the interpreter.
Steven Schveighoffer:
 Can you just ban slicing that escapes the statement?
Nov 13 2014
parent "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"Nick Treleaven"  wrote in message news:m42lbb$2pru$1 digitalmars.com... 

 This is:
 https://issues.dlang.org/show_bug.cgi?id=8838
 
 Apparently it's a bit tricky to implement ATM.
 
 yebblies:
 
  > This is not very easy, because the compiler lowers all static array
  > assignment to slice assignment, making _every_ static array assignment
  > unsafe.  That needs to be fixed first, and requires extensive changes 
  > in the interpreter.
I think the situation has slightly improved since.
Nov 13 2014
prev sibling parent "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Sunday, 9 November 2014 at 10:04:16 UTC, bearophile wrote:
 Yeah, what do you suggest to change in the language to avoid 
 this problem?
1. Deprecate dynamic arrays. 2. Implement dynamic arrays as a library type with it's own fat-slice implementation which supports reallocation (slices with indirection and stored begin/end indices). 3. Provide conversion to regular shrinkable slices for operations on the array with a warning similar to those provided by iterators in C++.
Nov 12 2014
prev sibling parent reply "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Sun, Nov 09, 2014 at 08:29:58AM +0000, AlanThinker via Digitalmars-d wrote:
 It seems that, D's array is strange,
 It can implicit convert static arrays to dynamic arrays no error and
 no warning.
 But when I return the converted arrays out the function.
 Outside function will get some wrong data.
 
 It may very easily cause some bug because no error when convert static
 arrays to dynamic arrays.
[...] Yes, this is a known problem. There may even be an issue filed in bugzilla about it (if not, please file one!). The problem is that local static arrays are allocated on the stack, and the implicit conversion to dynamic array is simply taking a slice of the stack-allocated array. As a result, after the function returns, the slice is now pointing at stack memory that has gone out of scope. I'm not sure if the current compiler issues a warning / error if you do this in safe code, but IMO it should do this even in system code since the implicit conversion is almost never correct. T -- People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird. -- D. Knuth
Nov 09 2014
parent reply "Don" <x nospam.com> writes:
On Sunday, 9 November 2014 at 15:09:10 UTC, H. S. Teoh via 
Digitalmars-d wrote:
 On Sun, Nov 09, 2014 at 08:29:58AM +0000, AlanThinker via 
 Digitalmars-d wrote:
 It seems that, D's array is strange,
 It can implicit convert static arrays to dynamic arrays no 
 error and
 no warning.
 But when I return the converted arrays out the function.
 Outside function will get some wrong data.
 
 It may very easily cause some bug because no error when 
 convert static
 arrays to dynamic arrays.
[...] Yes, this is a known problem. There may even be an issue filed in bugzilla about it (if not, please file one!). The problem is that local static arrays are allocated on the stack, and the implicit conversion to dynamic array is simply taking a slice of the stack-allocated array. As a result, after the function returns, the slice is now pointing at stack memory that has gone out of scope. I'm not sure if the current compiler issues a warning / error if you do this in safe code, but IMO it should do this even in system code since the implicit conversion is almost never correct. T
The problem is, that you need to be able to take a slice of a stack-allocked array (otherwise stack allocated arrays are useless). Eg you should be able to pass a slice of a stack array to writefln(). Detecting if the slice is returned, requires flow analysis. Currently the front-end doesn't do any flow analysis at all, except for a couple of special cases like closures and super() calls.
Nov 10 2014
next sibling parent "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Monday, 10 November 2014 at 08:29:40 UTC, Don wrote:
 stack-allocked array (otherwise stack allocated arrays are 
 useless). Eg you should be able to pass a slice of a stack 
 array to writefln().

 Detecting if the slice is returned, requires flow analysis. 
 Currently the front-end doesn't do any flow analysis at all, 
 except for a couple of special cases like closures and super() 
 calls.
Ceterum censeo ... http://wiki.dlang.org/User:Schuetzm/scope
Nov 10 2014
prev sibling parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 11/10/14 3:29 AM, Don wrote:
 The problem is, that you need to be able to take a slice of a
 stack-allocked array (otherwise stack allocated arrays are useless). Eg
 you should be able to pass a slice of a stack array to writefln().

 Detecting if the slice is returned, requires flow analysis. Currently
 the front-end doesn't do any flow analysis at all, except for a couple
 of special cases like closures and super() calls.
While all of that is true, the OP's code should be rejected. It returns a static array as a dynamic array in one expression. -Steve
Nov 10 2014