www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Weird behavior with "this T"

reply bauss <jj_1337 live.dk> writes:
Can someone explain the behavior of the following to me?

With a base class like this:

abstract class Foo
{
	string[] members;
	
	final:
	
	this(this T)(T child)
	{
		import std.conv : to;
		
		foreach (member; __traits(derivedMembers, T))
		{
			mixin("members ~= to!string(child." ~ member ~ ");\r\n");
		}
	}
	
	void printMembers()
	{
		writeln(members);
	}
}

I'd expect members to be populated with the values of the passed 
child type.

However the behavior is really weird.

The array members will be populated infinitely, which basically 
will cause the program to go out of memory.

If you change the mixin to this:

mixin("if (members.length < 20) members ~= to!string(child." ~ 
member ~ ");\r\n");

then you'll be able to see how the array is populated, but the 
values do not make sense in terms of how the code should work.

Example usage:

class Bar : Foo
{
	int baba;
	int caca;
	
	this() { baba = 1; caca = 2; super(this); }
}

class Baz : Foo
{
	int foo;
	int bar;
	int baz;
	
	this() { foo = 100; bar = 200; baz = 300; super(this); }
}

void main()
{
	auto b = new Bar();
	auto a = new Baz();
	
	b.printMembers();
	a.printMembers();
	b.printMembers();
}

The above code will produce an output like below:
["1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", 
"2", "1", "2", "1", "2", "1", "2", "f193.Bar", "f193.Bar", 
"f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", 
"f193.Bar", "f193.Bar"]
["100", "200", "300", "100", "200", "300", "100", "200", "300", 
"100", "200", "300", "100", "200", "300", "100", "200", "300", 
"100", "200", "f193.Baz", "f193.Baz", "f193.Baz", "f193.Baz", 
"f193.Baz", "f193.Baz"]
["1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", 
"2", "1", "2", "1", "2", "1", "2", "f193.Bar", "f193.Bar", 
"f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", 
"f193.Bar", "f193.Bar"]

Where I would have expected something like:
["1", "2"]
["100", "200", "300"]
["1", "2"]

Why exactly does it behave like this? It looks like a bug to me, 
but maybe there's a reason for the behavior?
Oct 19 2017
parent bauss <jj_1337 live.dk> writes:
On Thursday, 19 October 2017 at 17:53:43 UTC, bauss wrote:
 Can someone explain the behavior of the following to me?


 [...]
I figured this out. It was simply the constructor that was called recursive.
Oct 19 2017