On Saturday, 22 June 2013 at 13:48:53 UTC, Andrej Mitrovic wrote:
On 6/22/13, Andrej Mitrovic <andrej.mitrov...@gmail.com> wrote:
    Appender!(int[]) buffer;
    call(buffer);
    writeln(buffer.data);  // writes [], it's empty

Apparently it's the same thing as the old AA problem. Essentially the
buffer would have to be initialized first by appending:

-----
import std.array;
import std.stdio;

void call(Appender!(int[]) buffer)
{
    buffer.put(1);
}

void main()
{
    Appender!(int[]) buffer;
    call(buffer);
    assert(buffer.data.empty);  // passes

    call(buffer);
    assert(buffer.data.empty);  // still passes

    buffer.put(2);
    call(buffer);
assert(buffer.data == [2, 1]); // now it finally went through
}
-----

It has something to do with null-initialization. I remember the
discussion about this problem with hashes, I just can't remember if
there was a bug report about it to link to.

The problem occurs whenever the internal array is resized because what actually happens is that a new array is allocated and the contents copied over - the original Appender still references the original array (or in this case null). The last example only works because when you call "put(2)" it actually allocates an array large enough to hold at least another item as well.

As usual it can be solved by introducing an extra layer of indirection, either by passing by ref or by making Appender store a pointer to a range.

Reply via email to