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