digitalmars.D.learn - foreach: rvalue aggregate expression not finalized!
- Martin Kinkelin (95/95) Feb 20 2011 Hi again,
- Dmitry Olshansky (6/101) Feb 20 2011 It looks like the manifestation of
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.
Feb 20 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
Feb 20 2011