[Issue 5519] Saner struct equality

d-bugmail at puremagic.com d-bugmail at puremagic.com
Thu Feb 3 03:36:57 PST 2011


http://d.puremagic.com/issues/show_bug.cgi?id=5519


Denis Derman <denis.spir at gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |denis.spir at gmail.com


--- Comment #1 from Denis Derman <denis.spir at gmail.com> 2011-02-03 03:34:36 PST ---
(In reply to comment #0)
> Performing a comparison between two structs is a very common operation. Often
> structs contain strings and other things. Currently (DMD 2.051) the struct
> equality ignores the contents of strings contained inside structs, [...]
> 
> ----------------
> 
> struct Foo { string s; }
> void main() {
>     string s1 = "he";
>     string s2 = "llo";
>     string s3 = "hel";
>     string s4 = "lo";
>     auto f1 = Foo(s1 ~ s2);
>     auto f2 = Foo(s3 ~ s4);
>     assert((s1 ~ s2) == (s3 ~ s4));
>     assert(f1 == f2); // this asserts
> }
> 
> ----------------

This issue is partially masked by the fact sring /literals/ are interned in D
(or is it an implementation optimisation of dmd?). Very annoying in interaction
with the present issue: since string interning makes comparison of structs
holding string sometimes behave as expected, other cases have an increased risk
of being bug-prone. Below another example showing this (all asserts pass). Note
that idup does not help & restore correct behaviour observed in case of
literals:

struct S {string s;}
unittest {
    // literals
    string s01 = "hello"; string s02 = "hello";
    assert ( S(s01) == S(s02) );
    // concat
    string s1 = "he"; string s2 = "llo";
    string s3 = "hel"; string s4 = "lo";
    assert ( S(s1 ~ s2) != S(s3 ~ s4) );
    // slice
    string s = "hello";
    assert ( S(s[1..$-1]) != S("ell") );
    // idup'ed
    assert ( S(s[1..$-1].idup) != S("ell") );
    s5 = s[1..$-1].idup;
    assert ( S(s5) != S("ell") );
}

Denis

> ----------------
> 
> Surprisingly this works (DMD 2.051):
> 
> 
> struct Bar {
>     int x;
>     const bool opEquals(ref const(Bar) o) {
>         return x == o.x || x == -o.x;
>     }
> }
> struct Foo { Bar a; }
> void main() {
>     auto f1 = Foo(Bar(1));
>     auto f2 = Foo(Bar(-1));
>     assert(f1 == f2);  // this doesn't assert
> }
> 
> ----------------

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------


More information about the Digitalmars-d-bugs mailing list