Classic Dictionary inconsistency

Consider this code:

dim v1 as Int32 = -1
dim v2 as Int64 = -1

dim d as new Dictionary

d.Value( v1 ) = "something"
if d.HasKey( v2 )  then
  // Won't get here
end if

The same negative value will not match if they are originally cast differently. The new framework Dictionary handles this “correctly”. Bug?

since dictionary uses a HASHED value for the key and not the original value, I would expect this observation,

since one is hashing 0xFFFFFFFF
and the other is hashing 0xFFFFFFFFFFFFFFFF

Except the new framework Dictionary does not work this way, as mentioned.

but who knows if the hashing methods are the same or not… perhaps the new framework coerces Integers to Int64 first

which might make some sense, in order to get the same results if compiled 32bit vs 64bit… just guessing here

Agree, we don’t know, nor should we, but I’d expect (and did expect, to be frank) the behavior to be that of the new framework Dictionary. If I want to match against the value “-1”, I shouldn’t have to care how the key was cast. There would never be a time when I’d consider Int32( -1 ) and Int64( -1 ) to be different values.

Am I the only one who thinks this is a bug?

I talked myself into it being a bug. :slight_smile:

<https://xojo.com/issue/43513>

IMO it’s a bug, but i think the new framework is at fault, because as i understand the hashing is against the binary representation of the value and in this case -1 (32 bit) <> -1 (64 bit) and should generate different hashes. If the vartype shouldn’t be of influence then the vartype could just as easy be a float or double with the decimal representation value of -1 and those variables certainly are of different binary representation.
But as a hobbyist i would like someone explain exactly what is happening.

Its the way the binary value is hashed… I tried this with all different pairs of datatypes, with both positive and negative numbers
and the ONLY time it worked where the datatypes were not the same was if both values were ZERO

and perhaps it not the new framework is at fault, perhaps it is the new framework “fixed” it

This seems analogous to

  dim s1 as string = "123"
  dim s2 as string = "123"
  s2 = ConvertEncoding(s2, Encodings.UTF16LE)
  
  dim d as new dictionary
  
  d.value(s1) = s1
  
  if d.haskey(s2) then
    msgbox "has key"
  else
    msgbox "does not"
  end if

and DEFINITELY not new
Its probably existed since the sized types were introduced
I just tried it in 2008r5 and it behaves the same way there

…and we’d break a lot of code if the user depended on the different data types generating different keys.

You could subclass Dictionary and control the hashing yourself…

Personally i don’t think its a fix in the new framework but a bug or at least inconsistent behaviour regarding the old framework. This especially because it’s said that the new framework would have no automatic type conversions and without that, the dictionary in the new framework should deliver the same results provided that the mechanism for calculating the hashes is the same. I would expect them to be the same because otherwise the simple replacement of programs written in the old framework were much harder to translate to the new framework and that’s IMO unwanted.

But @Norman Palardy and @Greg O’Lone , is the dictionary in the new framework at fault or not, both of your answers don’t realy answer that, so PLEASE…

Auto’s comparison behavior at runtime matches what would happen at compile time. An Int32 with -1 and an Int64 with -1 will compare the same if the types were all spelled out, so Auto does too.

May i conclude then that it’s intentional inconsistent behaviour through automatic type conversion?

That doesn’t seem like something anyone would expect let alone depend on.

To be clear, I think this is a bug because it only affects NEGATIVE values.

Yeah… look at this adapted console example:

  dim neg1_32 as Int32 = -1
  dim neg1_64 as Int64 = -1
  
  dim d1 as new Dictionary
  
  d1.Value(neg1_32) = "something"
  if d1.HasKey(neg1_64)  then
    Print "d1 has key -1 (64)"
  else
    Print "d1 does NOT have key -1 (64)"
  end if
  
  dim one_32 as Int32 = 1
  dim one_64 as Int64 = 1
  
  dim d2 as new Dictionary
  
  d2.Value(one_32) = "something"
  if d2.HasKey(one_64) then
    Print "d2 has key 1 (64)"
  else
    Print "d2 does NOT have key 1 (64)"
  end if

The output of this console app shows:

d1 does NOT have key -1 (64)
d2 has key 1 (64)

If only affects NEGATIVE numbers if the two datatypes are different INTEGER datatypes (Int32 vs Int64)
It affects ALL non-zero numbers if the two datatypes are other types (Int32 vs Double for example)

This code works correctly too.

  dim i1 as Int32 = -1
  dim i2 as Int64 = -1
  
  if i1 = i2 then
    AddToResult "Ints are the same"
  end if
  
  dim v1 as variant = i1
  dim v2 as variant = i2
  
  if v1 = v2 then
    AddToResult "Variants are the same"
  end if

Kem… those examples do not involve HASHING, so you are comparing apples and oranges…

the same reason Norman said encoding of a hashed string would cause the key lookup to fail

I’m pointing out why a programmer would expect the Dictionary to match a negative integer regardless of type.