A Riddle: what is wrong with this code using std.array.Appender?

FeepingCreature feepingcreature at gmail.com
Mon Mar 25 20:10:32 UTC 2019


On Monday, 25 March 2019 at 18:21:12 UTC, Meta wrote:
> Ouch, you're right.
>
> import std.array: Appender;
>
> class Class
> {
>     Appender!(int[]) app = null;
> }
>
> void testAppender(Class c)
> {
>     import std.stdio;
>     writeln(c.app.data);
>     c.app ~= 10;
>     writeln(c.app.data);
> }
>
> void main()
> {
>     auto c1 = new Class();
>     auto c2 = new Class();
>     testAppender(c1);  //Prints [] and [10]
>     testAppender(c2); //Prints [10] and [10, 10]
> }
>
> I find that a bit strange, since you'd think that Appender 
> would initialize its payload on the first append; and it seems 
> like it does if you look at the code (in 
> Appender.ensureAddable). I'm not sure how it shakes out that 
> the two Appenders end up sharing the same memory.

Yep, that's correct. If you look at the AST analysis in 
run.dlang, what ends up happening is the constructor for Appender 
is evaluated statically as a side effect of "= null" becoming "= 
Appender(null)" and produces a static initializer referencing a 
shared global payload.


More information about the Digitalmars-d mailing list