digitalmars.D.bugs - [Issue 669] New: (a == b) misuses opCmp and opEquals
- d-bugmail puremagic.com (28/28) Dec 09 2006 http://d.puremagic.com/issues/show_bug.cgi?id=669
- d-bugmail puremagic.com (16/16) Dec 10 2006 http://d.puremagic.com/issues/show_bug.cgi?id=669
- d-bugmail puremagic.com (37/37) Dec 10 2006 http://d.puremagic.com/issues/show_bug.cgi?id=669
- d-bugmail puremagic.com (14/23) Dec 10 2006 http://d.puremagic.com/issues/show_bug.cgi?id=669
- d-bugmail puremagic.com (9/9) Dec 27 2006 http://d.puremagic.com/issues/show_bug.cgi?id=669
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
http://d.puremagic.com/issues/show_bug.cgi?id=669
smjg iname.com changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |smjg iname.com
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
http://d.puremagic.com/issues/show_bug.cgi?id=669
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
http://d.puremagic.com/issues/show_bug.cgi?id=669
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
http://d.puremagic.com/issues/show_bug.cgi?id=669
bugzilla digitalmars.com changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|NEW |RESOLVED
Resolution| |FIXED
Fixed DMD 0.178
--
Dec 27 2006









d-bugmail puremagic.com 