Unexpected aliasing

Antonio Corbi antonio at ggmail.com
Mon Nov 11 20:05:11 UTC 2019


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



More information about the Digitalmars-d-learn mailing list