www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 669] New: (a == b) misuses opCmp and opEquals

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=669

           Summary: (a == b) misuses opCmp and opEquals
           Product: D
           Version: 0.175
          Platform: PC
        OS/Version: Windows
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: bugzilla digitalmars.com
        ReportedBy: burton-radons smocky.com


This code:

   class C
   {
       override int opEquals (Object other) { return 0; }
       override int opCmp (Object other) { return 0; }
   }

   void main ()
   {
       auto a = new C, b = new C;
       assert (a != b);
   }

Asserts, because (a == b) is apparently implemented as (a.opEquals (b) ||
!a.opCmp (b)) for classes. If this were the way it should work, then "float.nan
== 0" would be true. It's the "!<>" operator that's defined with this
behaviour.


-- 
Dec 09 2006
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=669


smjg iname.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |smjg iname.com




------- Comment #1 from smjg iname.com  2006-12-10 12:12 -------
Under DMD 0.177, the code doesn't even compile:

opCmpEquals_2.d(9): semicolon expected following auto declaration, not ','
opCmpEquals_2.d(9): found ',' instead of statement

But having fixed this error, the bug doesn't show at all.  Experimenting shows
that:
== and != use only opEquals
<> and !<> use only opCmp
which is how it should be.

WFM?


-- 
Dec 10 2006
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=669





------- Comment #2 from burton-radons smocky.com  2006-12-10 13:43 -------
Grah I'm a stupid. Here's code which actually exhibits the problem:

        class C
        {
                override int opEquals (Object other) { printf ("opEquals\n");
return 0; }
                override int opCmp (Object other) { printf ("opCmp\n"); return
0; }
        }

        void main ()
        {
                auto type = typeid (typeof (C));
                void *data = new C;

                assert (type.equals (&data, &data) == 0);
        }

The fault is TypeInfo_Class in internal.object. It's implemented like this:

        int equals(void *p1, void *p2)
        {
                Object o1 = *cast(Object*)p1;
                Object o2 = *cast(Object*)p2;

                return o1 == o2 || (o1 && o1.opCmp(o2) == 0);
        }       

When it should be implemented like this:

        int equals(void *p1, void *p2)
        {
                Object o1 = *cast(Object*)p1;
                Object o2 = *cast(Object*)p2;

                return o1 == o2;
        }       

This problem showed itself because I was comparing boxed objects, so I assume
it's written the way it is now for associative arrays. If so then associative
arrays should have their own slot in a TypeInfo for performing this
(unorderedOrEqual), and std.boxer can have a pure form with the correct
semantics for ==. Otherwise std.boxer's Box.opEqualsInternal can have a clause
for objects.


-- 
Dec 10 2006
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=669





------- Comment #3 from smjg iname.com  2006-12-10 16:58 -------
(In reply to comment #2)
 When it should be implemented like this:
 
         int equals(void *p1, void *p2)
         {
                 Object o1 = *cast(Object*)p1;
                 Object o2 = *cast(Object*)p2;
 
                 return o1 == o2;
         }

I could've sworn this was fixed once! Moreover, that's still not quite right. It should be int equals(void *p1, void *p2) { if (p1 == null) return p2 == null; Object o1 = *cast(Object*)p1; Object o2 = *cast(Object*)p2; return o1 == o2; } or some equivalent of this. --
Dec 10 2006
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=669


bugzilla digitalmars.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |FIXED




------- Comment #4 from bugzilla digitalmars.com  2006-12-27 02:02 -------
Fixed DMD 0.178


-- 
Dec 27 2006