Passing Appender by value

Diggory diggsey at googlemail.com
Sat Jun 22 07:19:43 PDT 2013


On Saturday, 22 June 2013 at 13:48:53 UTC, Andrej Mitrovic wrote:
> On 6/22/13, Andrej Mitrovic <andrej.mitrovich at 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.


More information about the Digitalmars-d-learn mailing list