foreach: rvalue aggregate expression not finalized!

Martin Kinkelin noone at spam.com
Sun Feb 20 12:34:45 PST 2011


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.


More information about the Digitalmars-d-learn mailing list