On Monday, 11 November 2019 at 19:17:37 UTC, Bastiaan Veelo wrote:
Recently I got my first surprise with our use of D. The symptom was that two local variables in two different functions appeared to be sharing data.

A simplified example is shown below (the original was machine translated from Pascal and involved templates and various levels of indirection). What I did not know is that the initial value of struct members is a compile time feature, apparently. What I suspect is happening is that the array lives in the static data segment (or is created in the module constructor?) and that the slices inside arr1 and arr2 get initialised to point to that same array.

I could use some help in rewriting the code below so that arr1 and arr2 each have their own data; ideally with minimal changes so that I can make the transcompiler do the right thing.

Thanks!
Bastiaan.

void main()
{
        import std.stdio;

        WrapIntegerArray arr1;
        arr1[0] = 42;

        WrapIntegerArray arr2;

        writeln(arr2[0]); // 42, not 0.
        writeln("arr1.wrap.arr.ptr = ", arr1.wrap.arr.ptr);
writeln("arr2.wrap.arr.ptr = ", arr2.wrap.arr.ptr); // identical
        assert(arr2[0] == 0); // fails
}

struct IntegerArray
{
        int[] arr;
        alias arr this;
        this(int l)
        {
                arr = new int[l];
        }
}

struct WrapIntegerArray
{
        auto wrap = IntegerArray(5); // This is CTFE! :-(
        alias wrap this;
}


Defining and using a constructor for WrapIntegerArray seems to work:

void main()
{
        import std.stdio;

        WrapIntegerArray arr1 = WrapIntegerArray(5);
        arr1[0] = 42;

        WrapIntegerArray arr2 = WrapIntegerArray(5);

        writeln(arr2[0]); // 42, not 0.
        writeln("arr1.wrap.arr.ptr = ", arr1.wrap.arr.ptr);
        writeln("arr2.wrap.arr.ptr = ", arr2.wrap.arr.ptr); // identical
        assert(arr2[0] == 0); // fails
}

struct IntegerArray
{
        int[] arr;
        alias arr this;
        this(int l)
        {
                arr = new int[l];
        }
}

struct WrapIntegerArray
{
        this (int v) {
          wrap = IntegerArray(5);
        }

        IntegerArray wrap;
        alias wrap this;
}

Hope this helps.
Antonio

Reply via email to