Bug 10525 – Struct as key in Associative array ignores value semantics

Status
RESOLVED
Resolution
DUPLICATE
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-07-02T02:06:00Z
Last change time
2014-07-04T17:35:41Z
Assigned to
nobody
Creator
michal.minich

Comments

Comment #0 by michal.minich — 2013-07-02T02:06:31Z
DMD 2.063.2 struct S { char[] str; } void main () { auto s1 = S(cast(char[])"abc"); auto s2 = S(cast(char[])"Xbc"); // indirect members in structs are compared by value assert (s1 != s2); // ok, structs are compared not equal s2.str[0] = 'a'; assert (s1 == s2); // ok, structs are compared equal // not so in AA auto aa = [s1 : 1]; auto s1aa = s1 in aa; assert (s1aa); auto s2aa = s2 in aa; assert (s2aa); // fails, but should pass // s2 should be found in aa the same way as s1 }
Comment #1 by hsteoh — 2013-07-08T15:09:40Z
This is not really a bug. Structs by default are bitwise-compared. If you want structs to be deep-compared, you need to define toHash and opCmp: struct S { char[] str; size_t toHash() const { // Just use arrays' builtin hash function, no need to reinvent your own return typeid(str).getHash(&str); } // Note: this exact function signature must be used; // DMD is currently very picky about this. int opCmp(ref const S s) const { return typeid(str).compare(&str, &s.str); } } Once these two pieces are in place, your struct should work correctly as AA key.
Comment #2 by michal.minich — 2013-07-11T03:29:28Z
(In reply to comment #1) > This is not really a bug. Structs by default are bitwise-compared. This is a bug. structs are deeply compared by default as of last dmd release. I included an example of that in the bug report code.
Comment #3 by k.hara.pg — 2014-07-04T17:35:41Z
Struct equality is now member-wise, and runtime hash calculation (TypeInfo.getHash) should be consistent with the equality result. With two equivalent type objects a and b, it should be guaranteed: assert(a != b || typeid(typeof(a)).getHash(&a) == typeid(typeof(b)).getHash(&b)); *** This issue has been marked as a duplicate of issue 13045 ***