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