Beginner problem: casting in opCmp override

Jonathan M Davis jmdavisProg at gmx.com
Mon Jul 8 17:09:14 PDT 2013


On Monday, July 08, 2013 16:58:03 H. S. Teoh wrote:
> 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?

Yes. opCmp's behavior should definitely match opEquals' behavior.

- Jonathan M Davis


More information about the Digitalmars-d-learn mailing list