Typeinfo.compare and opCmp woes

H. S. Teoh hsteoh at quickfur.ath.cx
Sun Jul 7 21:44:59 PDT 2013


I have a partial fix for issues 8435 and 10118, but it's being blocked
by issue 10567. Basically, the problem is that opCmp *must* be declared
as:

	struct T {
		int opCmp(ref const T t) const { ... }
	}

Only when it's declared this way, will T's typeinfo.compare pick up the
correct custom opCmp.

If 'ref' is dropped, typeinfo.compare reverts to the default bitwise
opCmp.

If opCmp is a template function, typeinfo.compare reverts to the default
bitwise opCmp.

If any of the const's are dropped, typeinfo.compare reverts to the
default bitwise opCmp.

This is *in spite* of the fact that == works perfectly fine in all of
these cases.

This makes it basically impossible to use structs with custom opCmp as
AA keys, because AA's use typeinfo.compare for key comparisons. When any
of the above conditions happen, == and typeinfo.compare are inconsistent
with each other, and the AA will malfunction. So you have bugs like:

	int[T] aa;

	auto t = T;
	auto u = t;
	assert(t==u); // N.B. t and u are equal
	assert(typeid(t).getHash(&t) == typeid(u).getHash(&u)); // OK

	aa[t] = 1;
	assert(u in aa);	// fails
	aa[u] = 2;
	assert(aa[t] == 2);	// fails
	assert(std.algorithm.count(aa.keys) == 1);	// fails

	// This is the cause of the problem:
	assert(typeid(t).compare(&t, &u)==0); // fails

:-(

Bugzilla: http://d.puremagic.com/issues/show_bug.cgi?id=10567


T

-- 
Customer support: the art of getting your clients to pay for your own incompetence.


More information about the Digitalmars-d mailing list