D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 7564 - Implicit conversion from static to dynamic array in loops
Summary: Implicit conversion from static to dynamic array in loops
Status: RESOLVED INVALID
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P2 normal
Assignee: No Owner
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-02-22 15:24 UTC by Sebastian
Modified: 2015-06-09 01:31 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Sebastian 2012-02-22 15:24:43 UTC
import std.stdio;

void main()
{
    int[][] a;
    a.length = 3;

    for(int i; i<3; i++) {
      int[1] b;
      b[0] = i; 
      a[i] = b;
      writeln(a);
    }
}

Result:
[[0], [], []]
[[1], [1], []]
[[2], [2], [2]]

I expected the result:
[[0], [], []]
[[0], [1], []]
[[0], [1], [2]]
Comment 1 bearophile_hugs 2012-02-22 16:04:17 UTC
I think there is no bug here.

This line:
a[i] = b;

means
a[i] = b[];

That means:
a[i].ptr = b.ptr;
a[i].length = b.length;

So every time you are rebinding a[i] to the same memory location.

See the output of this program:


import std.stdio, std.algorithm;

void foo(int[][] a) {
    foreach (i; 0 .. 3) {
      int[1] b = i;
      a[i] = b[];
      writeln(a, " ", map!(row => row.ptr)(a));
    }
}

void main() {
    int[][] a;
    a.length = 3;

    foo(a);
    writeln(a);
}


Your output is generated by:

import std.stdio, std.algorithm;
void main() {
    int[][] a;
    a.length = 3;

    foreach (i; 0 .. 3) {
      int[1] b = i;
      a[i] = b[].dup;
      writeln(a);
    }
}
Comment 2 Sebastian 2012-02-23 13:40:11 UTC
Ok, I understand, I was wrong. However on a related matter, I think that,
import std.stdio;
int[1] f(int i)
{
  int[1] a = i;
  return a;
}
void main() {
   foreach (i; 0 .. 2) {
     writeln(f(i).ptr);
   }
  writeln(f(0).ptr);
  writeln(f(1).ptr);
}

prints
7FFFF03A05E0
7FFFF03A05E0
7FFFF03A05E4
7FFFF03A05E8

is a little bit strange, but I guess that just how it works.
Comment 3 Kenji Hara 2012-02-23 14:48:52 UTC
Temporary objects are destroyed ad the scope end, not statement end.

(In reply to comment #2)
> Ok, I understand, I was wrong. However on a related matter, I think that,
> import std.stdio;
> int[1] f(int i)
> {
>   int[1] a = i;
>   return a;
> }
> void main() {
>    foreach (i; 0 .. 2) {
>      writeln(f(i).ptr);

is same as:
       auto tmp = f(i); writefln(tmp.ptr);
       // tmp is destroyed at the end of foreach, so prints same address

>    }
>   writeln(f(0).ptr);
>   writeln(f(1).ptr);

are same as:
       auto tmp1 = f(i); writefln(tmp1.ptr);
       auto tmp2 = f(i); writefln(tmp2.ptr);
       // each temporaries has own memory, so prints different address

> }
> 
> prints
> 7FFFF03A05E0
> 7FFFF03A05E0
> 7FFFF03A05E4
> 7FFFF03A05E8
> 
> is a little bit strange, but I guess that just how it works.
Comment 4 bearophile_hugs 2012-02-23 16:58:52 UTC
I close this, there is a bug, but it's reported elsewhere in bugzilla ( Issue 7444 ).