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