ref semantics with hashes

Andrej Mitrovic andrej.mitrovich at gmail.com
Wed May 2 12:38:35 PDT 2012


import std.stdio;

struct Foo
{
    int[int] hash;
}

void main()
{
    test1();
    test2();
}

void test1()
{
    Foo foo;
    foo.hash[1] = 1;

    auto hash2 = foo.hash;
    hash2[2] = 2;
    writeln(foo.hash);  // [1:1, 2:2]
    writeln(hash2);     // [1:1, 2:2]
}

void test2()
{
    Foo foo;
    auto hash2 = foo.hash;
    hash2[2] = 2;
    writeln(foo.hash);  // [] ??
    writeln(hash2);     // [2:2]
}

So if the hash wasn't already initialized then the reference in the
Foo struct is a reference to null, and if you duplicate that reference
and add a key the old reference still points to null.

The only way to ensure a proper link with a hash is to initialize it
with a key and then immediately remove that key, which makes the hash
not-null but empty:

import std.stdio;

class Foo
{
    int[int] hash;
    this() { hash[0] = 0; hash.remove(0); }  // make it not null but empty
}

void main()
{
    test1();
    test2();
}

void test1()
{
    Foo foo = new Foo;
    foo.hash[1] = 1;

    auto hash2 = foo.hash;
    hash2[2] = 2;
    writeln(foo.hash);  // [1:1, 2:2]
    writeln(hash2);     // [1:1, 2:2]
}

void test2()
{
    Foo foo = new Foo;
    auto hash2 = foo.hash;
    hash2[2] = 2;
    writeln(foo.hash);  // [2:2]
    writeln(hash2);     // [2:2]
}

Why do we have such error-prone semantics?


More information about the Digitalmars-d-learn mailing list