Beginner problem: casting in opCmp override

H. S. Teoh hsteoh at quickfur.ath.cx
Mon Jul 8 16:58:03 PDT 2013


On Mon, Jul 08, 2013 at 04:48:05PM -0700, Jonathan M Davis wrote:
> On Monday, July 08, 2013 16:38:16 H. S. Teoh wrote:
[...]
> > Basically, when you write x==y, the compiler looks for opEquals and
> > opCmp. If opEquals is found, then it's rewritten as x.opEquals(y);
> > otherwise, if opCmp is found, it's rewritten as x.opCmp(y)==0. If
> > neither are found, then the compiler generates a default
> > implementation of opEquals, which basically does a bitwise
> > comparison of x and y.
> 
> Actually, what it's supposed to do isn't necessarily a bitwise
> comparison.  It's supposed to do a recursive comparison of all of the
> members, where it calls == on each of the members. If a bitwise
> comparison will do that, then it may end up as a bitwise comparison
> for efficiency reasons, but it's not necessarily a bitwise comparison.
> It used to be that it was doing a bitwise comparison when it wasn't
> supposed to, but that was fixed fairly recently (though I don't recall
> if that fix has been released yet).
> 
> Basically, there's no reason to overload opEquals unless you have a
> member which you don't want to compare with == (e.g. pointers).
[...]

Unfortunately, this isn't true for opCmp. If you don't define opCmp, the
typeinfo of the struct will have a compare function that basically does
bitwise comparison. Proof:

	struct S {
		int[] data;
	}
	void main() {
		auto s = S([1,2,3]);
		auto t = S([1,2,3]);
		auto u = S([1,2,4]);

		assert(s == t);
		assert(s != u);
		assert(typeid(s).compare(&s, &t) == 0); // FAILS
		assert(typeid(s).compare(&s, &u) != 0);
	}

Should this be filed as a DMD bug?


T

-- 
A computer doesn't mind if its programs are put to purposes that don't match their names. -- D. Knuth


More information about the Digitalmars-d-learn mailing list