One of my favourite #dlang's traps is postbliting aka the way dlang implements default values for fields.
In other languages, initializer (or default values) of fields are essentially just syntactic sugar and get compiled (more or less) to assignments into each of the declared contructors.
Not so in dlang however. It creates an instance at compiletime (of the class in this case) without running constructors and "snapshots" it. This is then used in the compiled binary whenever an instance is created: the snapshot is memcpy'd over to the newly allocated instance. The problem is, that this includes any field that is a pointer / a class!!! So if you have an member field which type is a class itself and you write an initializer to create that class with the new
keyword, this instance is put into static memory and each instance of the class you've done this in now holds the same reference to that statically allocated instance. Each and everyone of them, and it's completly against my mental picture of field initilizers (and I assume for a lot of others as well).
Just stumpled about this again while debugging a template system I've wrote [code.dlang.org], where I experimented with moving the bound functions of a template into a "common" class so it's easier to share them with templates that are grouped together (i.e. sub-templates or "blocks"). Moved the fields around and without actually assigning the "common" class to the sub templates the tests magically started working and I didn't know why. Makes sense now, since they've just had recieved all the same reference to the same static instance of the "common" class.
Example code:
class Other {}
class Test {
Other o = new Other();
}
void main() {
import std.stdio;
auto t1 = new Test();
auto t2 = new Test();
writeln("t1.o: ", cast(void*) t1.o);
writeln("t2.o: ", cast(void*) t2.o);
}