foreach: rvalue aggregate expression not finalized!

Dmitry Olshansky dmitry.olsh at gmail.com
Sun Feb 20 13:18:52 PST 2011


On 20.02.2011 23:34, Martin Kinkelin wrote:
> Hi again,
>
> I just came across something odd - if the aggregate expression in a
> foreach statement constructs a new struct (returning an rvalue), it
> isn't finalized (well, to be precise, its implicit copy isn't).
>
> Test:
> ----------
> import std.stdio;
>
> struct A
> {
>      int[3] _data;
>      string _name;
>
>      this(string name) { writeln("A.__ctor() for ", name); _name = name; }
>      ~this() { writeln("A.__dtor() for ", _name); }
>      this(this) { _name ~= "2"; writeln("Postblit constructor for ", _name); }
>
>      A dup()
>      {
>          A r = A(_name ~ ".dup");
>          r._data[] = _data[];
>          return r;
>      }
>
>      int opApply(int delegate(ref int) dg)
>      {
>          int r = 0;
>          for (int i = 0; i<  _data.length; i++)
>          {
>              r = dg(_data[i]);
>              if (r)
>                  break;
>          }
>          return r;
>      }
> }
>
> unittest
> {
>      A a = A("a");
>      a._data = [ 1, 2, 3 ];
>
>      writeln("Iterating through a:");
>      foreach (ref e; a)
>          writeln(e);
>
>      writeln("\nIterating through a.dup:");
>      {
>          foreach (ref e; a.dup)
>              writeln(e);
>          writeln("ending inner scope");
>      }
>      writeln("inner scope ended");
> }
> ----------
>
> Output:
> ----------
> A.__ctor() for a
> Iterating through a:
> 1
> 2
> 3
>
> Iterating through a.dup:
> A.__ctor() for a.dup
> Postblit constructor for a.dup2
> A.__dtor() for a.dup
> 1
> 2
> 3
> ending inner scope
> inner scope ended
> A.__dtor() for a
> ----------
>
> The problem is remedied by assigning a.dup manually to an lvalue and iterating
> over that:
> ----------
> ...
>          A dup = a.dup;
>          foreach (ref e; dup)
> ...
> ----------
>
> Output:
> ----------
> A.__ctor() for a
> Iterating through a:
> 1
> 2
> 3
>
> Iterating through a.dup:
> A.__ctor() for a.dup
> Postblit constructor for a.dup2
> A.__dtor() for a.dup
> 1
> 2
> 3
> ending inner scope
> A.__dtor() for a.dup2
> inner scope ended
> A.__dtor() for a
> ----------
>
> I just figured this out and think it should be considered as bug as it is far
> from obvious, at least from my point of view.
It looks like the manifestation of
http://d.puremagic.com/issues/show_bug.cgi?id=3516
vote up ! ;)

-- 
Dmitry Olshansky



More information about the Digitalmars-d-learn mailing list