On Wednesday, 28 May 2014 at 07:13:37 UTC, BlackEdder wrote:
I'm trying to write a thin wrapper around redblacktree, but it seems every object of the class shares the same copy of redblacktree. Am I doing something wrong or is this a bug.

Minimal code example:

import std.array;
import std.container;
import std.stdio;

class A {
    auto tree = new RedBlackTree!string();
}

unittest {
    auto a = new A();
    a.tree.insert( "a" );
    auto b = new A();
    writeln( "Should be empty, but is: ", b.tree.array );
writeln( "Should be empty, but has length: ", b.tree.length );
}

Which results in the following output:
$ rdmd -unittest rbt.d
Should be empty, but is: ["a"]
Should be empty, but has length: 1


I'm using dmd 2.0.65.

The problem is the initialization of A.tree. Short answer, move it to a constructor and it should work.

Now what I think is going on: default values for member fields must be known at compile time. This is why structs can do something like

struct S
{
  int i = 5;
}

while they're not allowed to define a default constructor.

So it appears the tree is instantiated at compile time and stored somewhere, and the reference to that instance is used as the default value for A.tree. I didn't know this was possible to do with reference type members, and perhaps it should be disallowed. This is highly counter intuitive behavior esp. for people coming from Java.

Reply via email to