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








Dmitry Olshansky <dmitry.olsh gmail.com>