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 ***