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