How do I obtain the default hash of a user-defined struct

dnspies dspies at ualberta.ca
Thu Apr 3 15:32:13 PDT 2014


On Thursday, 3 April 2014 at 21:42:18 UTC, bearophile wrote:
> dnspies:
>
>> This doesn't work.  It prints two different hashes for equal 
>> objects.  I meant how do I get the default hash which is used 
>> by an associative array.
>>
>> import std.stdio;
>>
>> struct my_struct {
>> 	int[] arr;
>> }
>>
>> void main() {
>> 	my_struct s1;
>> 	s1.arr = [1,2,3];
>> 	my_struct s2;
>> 	s2.arr = [1,2,3];
>> 	writeln(s1 == s2);
>> 	writeln(typeid(my_struct).getHash(&s1));
>> 	writeln(typeid(my_struct).getHash(&s2));
>> }
>>
>> true
>> 626617119
>> 2124658624
>
> Take a look at the output of this program:
>
> import std.stdio;
>
> struct MyStruct {
>      int[] arr;
> }
>
> void main() {
>      MyStruct s1;
>      s1.arr = [1,2,3];
>      MyStruct s2;
>      s2.arr = [1,2,3];
>      writeln(s1 == s2);
>      writeln(typeid(MyStruct).getHash(&s1));
>      writeln(typeid(MyStruct).getHash(&s2));
>
>      int[MyStruct] aa;
>      aa[s1] = 10;
>      aa[s2] = 20;
>      writeln(aa);
> }
>
>
> I have filed this big problem four years ago or more.
>
> Workarounds: define (carefully!) the three hash protocol 
> methods, or use a tuple.
>
> Bye,
> bearophile

Oh so the problem isn't that that ISN'T the default hash used by 
an AA.  It's worse.  The problem is that that IS the default hash 
used by an AA.

When you say "use a tuple", do you mean that the hash 
implementation for Tuples is defined recursively and based on its 
members' hashes?  There doesn't seem to be an opHash for Tuples 
AFAICT.  If not, could you provide an example?

Also, if this problem isn't going to be fixed any time soon, 
shouldn't it be documented directly on the AA page somewhere?  
It's just the sort of surprise that I would have no hope of 
figuring out when trying to debug my program.  (I put this 
wrapped_string into my AA, but when I try to fetch it again, it's 
disappeared!!??)

What's worse, there's no link provided to TypeInfo.getHash, 
instead it just says "If the KeyType is a struct or union type, a 
default mechanism is used to compute the hash and comparisons of 
it based on the binary data within the struct value" which sounds 
as though they're saying "don't worry, we've handled everything" 
which is the opposite of true.


More information about the Digitalmars-d-learn mailing list