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
Permalink
Reply