WAT: opCmp and opEquals woes

Ary Borenszweig via Digitalmars-d digitalmars-d at puremagic.com
Wed Jul 23 10:15:10 PDT 2014


On 7/23/14, 1:45 PM, H. S. Teoh via Digitalmars-d wrote:
> This morning, I discovered this major WAT in D:
>
> ----
> struct S {
>          int x;
>          int y;
>          int opCmp(S s) {
>                  return x - s.x; // compare only x
>          }
> }
>
> void main() {
>          auto s1 = S(1,2);
>          auto s2 = S(1,3);
>          auto s3 = S(2,1);
>
>          assert(s1 < s3); // OK
>          assert(s2 < s3); // OK
>          assert(s3 > s1); // OK
>          assert(s3 > s2); // OK
>          assert(s1 <= s2 && s2 >= s1); // OK
>          assert(s1 == s2); // FAIL -- WAT??
> }
> ----
>
> The reason for this is that the <, <=, >=, > operators are defined in
> terms of opCmp (which, btw, is defined to return 0 when the objects
> being compared are equal), but == is defined in terms of opEquals. When
> opEquals is not defined, it defaults to the built-in compiler
> definition, which is a membership equality test, even if opCmp *is*
> defined, and returns 0 when the objects are equal.
>
> Why isn't "a==b" rewritten as "a.opCmp(b)==0"?? I'm pretty sure TDPL
> says this is the case (unfortunately I'm at work so I can't check my
> copy of TDPL).
>
> https://issues.dlang.org/show_bug.cgi?id=13179
>
> :-(
>
>
> T

Imagine you have a list of integers and strings denoting integers: [1, 
"2", 100, "38"]. Now you want to sort them according to their numeric 
value. Of course, 1 and "1" would have the same order. However, 1 and 
"1" are different, so "==" would give false, while 1.opCmp("1") would 
give 0.

Equality and comparison are different. opCmp is used for sorting 
objects, which has nothing to do with equality. Inferring equality from 
opCmp is wrong in my opinion.


More information about the Digitalmars-d mailing list