February 20, 2011 foreach: rvalue aggregate expression not finalized! | ||||
---|---|---|---|---|
| ||||
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. |
February 20, 2011 Re: foreach: rvalue aggregate expression not finalized! | ||||
---|---|---|---|---|
| ||||
Posted in reply to Martin Kinkelin | 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 |
Copyright © 1999-2021 by the D Language Foundation