Weird behavior with "this T"

bauss jj_1337 at live.dk
Thu Oct 19 17:53:43 UTC 2017


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?


More information about the Digitalmars-d mailing list