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