Re: deep copy or shallow copy?

2011-12-09 Thread Ali Çehreli

On 12/08/2011 12:52 PM, Timon Gehr wrote:
 On 12/08/2011 09:50 PM, RenatoL wrote:
 snippet 1)
 auto arr1 = [1,2,3];
 auto arr2 = arr1;
 arr1[1] = 22;
 arr2[2] = 33;
 foreach (i; 0..arr1.length) write(arr1[i],  );
 writeln();
 foreach (i; 0..arr2.length) write(arr2[i],  );

 output:
 1 22 33
 1 22 33
 OK

 snippet 2)

 int[3] arr1 = [1,2,3];
 int[3] arr2 = arr1;
 arr1[1] = 22;
 arr2[2] = 33;
 foreach (i; 0..arr1.length) write(arr1[i],  );
 writeln();
 foreach (i; 0..arr2.length) write(arr2[i],  );

 output:

 1 22 3
 1 2 33

 that's unclear to me... i agree with the behaviour of the
 dynamic array... but if we have a static array we have a deep copy?

 Both copies are 'shallow', but static arrays are value types.

'shallow' would be misleading for a fixed-length (static) array because 
there is nothing else but the elements for fixed-length arrays:


void main()
{
int[3] a;
assert(cast(void*)a == cast(void*)a[0]);
}

Fixed-length array storage is similar to C arrays. These are different:

- they don't decay to a 'pointer to first element' when passed to 
functions (being value types, the whole array is copied)


- a.length is a convenience, equivalent to a.sizeof / a[0].sizeof

So it is impossible to do anything shallow with them unless we 
explicitly maintain a pointer to a fixed-length array ourselves.


Ali



Re: deep copy or shallow copy?

2011-12-09 Thread Timon Gehr

On 12/09/2011 09:32 PM, Ali Çehreli wrote:

On 12/08/2011 12:52 PM, Timon Gehr wrote:
  On 12/08/2011 09:50 PM, RenatoL wrote:
  snippet 1)
  auto arr1 = [1,2,3];
  auto arr2 = arr1;
  arr1[1] = 22;
  arr2[2] = 33;
  foreach (i; 0..arr1.length) write(arr1[i],  );
  writeln();
  foreach (i; 0..arr2.length) write(arr2[i],  );
 
  output:
  1 22 33
  1 22 33
  OK
 
  snippet 2)
 
  int[3] arr1 = [1,2,3];
  int[3] arr2 = arr1;
  arr1[1] = 22;
  arr2[2] = 33;
  foreach (i; 0..arr1.length) write(arr1[i],  );
  writeln();
  foreach (i; 0..arr2.length) write(arr2[i],  );
 
  output:
 
  1 22 3
  1 2 33
 
  that's unclear to me... i agree with the behaviour of the
  dynamic array... but if we have a static array we have a deep copy?
 
  Both copies are 'shallow', but static arrays are value types.

'shallow' would be misleading for a fixed-length (static) array because
there is nothing else but the elements for fixed-length arrays:


It is not misleading since the array might be an array of references. 
(and if it does not contain references, shallow and deep are the same 
thing anyway)




void main()
{
int[3] a;
assert(cast(void*)a == cast(void*)a[0]);
}

Fixed-length array storage is similar to C arrays. These are different:

- they don't decay to a 'pointer to first element' when passed to
functions (being value types, the whole array is copied)

- a.length is a convenience, equivalent to a.sizeof / a[0].sizeof

So it is impossible to do anything shallow with them unless we
explicitly maintain a pointer to a fixed-length array ourselves.

Ali



You can always slice it, of course

int[3] a;
int[] b = a[]; // b now is a dynamic array that aliases a's contents




Re: deep copy or shallow copy?

2011-12-09 Thread Jonathan M Davis
On Friday, December 09, 2011 22:09:15 Timon Gehr wrote:
 On 12/09/2011 09:32 PM, Ali Çehreli wrote:
  So it is impossible to do anything shallow with them unless we
  explicitly maintain a pointer to a fixed-length array ourselves.
  
  Ali
 
 You can always slice it, of course
 
 int[3] a;
 int[] b = a[]; // b now is a dynamic array that aliases a's contents

Though, of course, you have to be careful with that, since the static array 
then owns the memory for that dynamic array, and if the static array goes out 
of scope before the dynamic array does, then the dynamic array points to 
garbage and will result in bugs.

- Jonathan M Davis


Re: deep copy or shallow copy?

2011-12-09 Thread Ali Çehreli

On 12/09/2011 01:18 PM, Jonathan M Davis wrote:
 On Friday, December 09, 2011 22:09:15 Timon Gehr wrote:
 On 12/09/2011 09:32 PM, Ali Çehreli wrote:
 So it is impossible to do anything shallow with them unless we
 explicitly maintain a pointer to a fixed-length array ourselves.

 Ali

 You can always slice it, of course

 int[3] a;
 int[] b = a[]; // b now is a dynamic array that aliases a's contents

 Though, of course, you have to be careful with that, since the static 
array
 then owns the memory for that dynamic array, and if the static array 
goes out

 of scope before the dynamic array does, then the dynamic array points to
 garbage and will result in bugs.

 - Jonathan M Davis

That's news to me. Don't the static array elements belong to the 
runtime, managed by the garbage collector, and will be kept alive as 
long as the slice is alive?


Ali



Re: deep copy or shallow copy?

2011-12-09 Thread Jonathan M Davis
On Friday, December 09, 2011 14:33:38 Ali Çehreli wrote:
 On 12/09/2011 01:18 PM, Jonathan M Davis wrote:
  On Friday, December 09, 2011 22:09:15 Timon Gehr wrote:
  On 12/09/2011 09:32 PM, Ali Çehreli wrote:
  So it is impossible to do anything shallow with them unless we
  explicitly maintain a pointer to a fixed-length array ourselves.
  
  Ali
  
  You can always slice it, of course
  
  int[3] a;
  int[] b = a[]; // b now is a dynamic array that aliases a's contents
  
  Though, of course, you have to be careful with that, since the static
 
 array
 
  then owns the memory for that dynamic array, and if the static array
 
 goes out
 
  of scope before the dynamic array does, then the dynamic array points
  to
  garbage and will result in bugs.
  
  - Jonathan M Davis
 
 That's news to me. Don't the static array elements belong to the
 runtime, managed by the garbage collector, and will be kept alive as
 long as the slice is alive?

Goodness no. The static array is on the stack, not on the heap. If you append 
to a dynamic array which refers to a static array, then it'll reallocate that 
memory onto the heap (leaving the original static array alone) so that the 
dynamic array is then managed by the runtime, but the static array never is, 
since it's on the stack, and as long as the dynamic array is a slice of the 
static array, it's going to be pointing to the wrong thing if the static array 
leaves scope.

So, slicing a static array to pass it to a function which isn't going to keep 
the memory around isn't a big deal, but doing something like

int[] func()
{
 int[5] a;
 return a[];
}

is as bad as

int* func()
{
 int a;
 return a;
}

though at least in the second case, the compiler will give you an error. The 
first probably should as well, but it doesn't currently. It _is_ escaping a 
reference to a local variable though, which is a bug.

- Jonathan M Davis


Re: deep copy or shallow copy?

2011-12-09 Thread Ali Çehreli

On 12/09/2011 02:58 PM, Jonathan M Davis wrote:
 On Friday, December 09, 2011 14:33:38 Ali Çehreli wrote:
[...]
 That's news to me. Don't the static array elements belong to the
 runtime, managed by the garbage collector, and will be kept alive as
 long as the slice is alive?

 Goodness no. The static array is on the stack, not on the heap. If 
you append
 to a dynamic array which refers to a static array, then it'll 
reallocate that
 memory onto the heap (leaving the original static array alone) so 
that the
 dynamic array is then managed by the runtime, but the static array 
never is,
 since it's on the stack, and as long as the dynamic array is a slice 
of the
 static array, it's going to be pointing to the wrong thing if the 
static array

 leaves scope.

 So, slicing a static array to pass it to a function which isn't going 
to keep

 the memory around isn't a big deal, but doing something like

 int[] func()
 {
   int[5] a;
   return a[];
 }

 is as bad as

 int* func()
 {
   int a;
   returna;
 }

 though at least in the second case, the compiler will give you an 
error. The
 first probably should as well, but it doesn't currently. It _is_ 
escaping a

 reference to a local variable though, which is a bug.

 - Jonathan M Davis

Thank you. Opened:

  http://d.puremagic.com/issues/show_bug.cgi?id=7087

Ali



Re: deep copy or shallow copy?

2011-12-08 Thread Timon Gehr

On 12/08/2011 09:50 PM, RenatoL wrote:

snippet 1)
auto arr1 = [1,2,3];
auto arr2 = arr1;
arr1[1] = 22;
arr2[2] = 33;
foreach (i; 0..arr1.length) write(arr1[i],  );
writeln();
foreach (i; 0..arr2.length) write(arr2[i],  );

output:
1 22 33
1 22 33
OK

snippet 2)

int[3] arr1 = [1,2,3];
int[3] arr2 = arr1;
arr1[1] = 22;
arr2[2] = 33;
foreach (i; 0..arr1.length) write(arr1[i],  );
writeln();
foreach (i; 0..arr2.length) write(arr2[i],  );

output:

1 22 3
1 2 33

that's unclear to me... i agree with the behaviour of the
dynamic array... but if we have a static array we have a deep copy?


Both copies are 'shallow', but static arrays are value types.