Forum > General

[solved] Strange behavior in generics.collections TDictionary

(1/3) > >>

piola:
Consider the following code:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---program project1; {$mode objfpc}{$longstrings on} // see output below{$modeswitch advancedrecords} uses Variants, Generics.Collections, SysUtils; type TRecord = packed record  FID: NativeUInt;  FKey: String;  constructor Create (AID: NativeUInt; AKey: String);end; constructor TRecord.Create (AID: NativeUInt; AKey: String);begin  FID := AID;  FKey := UpperCase (AKey);end; var  Dict: specialize TDictionary<TRecord,Variant>;  i: specialize TPair<TRecord,Variant>; begin  Dict := specialize TDictionary<TRecord,Variant>.Create;  Dict.Add (TRecord.Create (1, 'test'), 1);  for i in Dict do Writeln (i.Key.FID, #9, i.Key.FKey, #9, i.Value);  // ^^^ 1 TEST 1  // -> so the entry is ok!  Writeln (Dict.ContainsKey (TRecord.Create (1, 'test')));  // ^^^ with longstrings on -> FALSE  //     with longstrings off -> TRUE  Writeln (Dict.ContainsKey (TRecord.Create (1, 'TEST')));  // ^^^ always FALSE  Dict.Free;end. 
I'm very confused... I have no idea if I'm overseeing something or this is a bug in generics.collections or in the compiler.

My system is:
Lazarus 2.2.0 (64 bit), FPC 3.2.2 (64 bit) on Windows 8.1 (64 bit)

Thaddy:
generics.collections is compiled in{$H+} mode so longstrings are always on, unless you specialize explicitly to shortstring.
Note that your example outputs true/false here, both on Linux and Win64. You expected that?
Only thing I changed was to change string to shortstring and then tested with changing string to AnsiString.

BTW two remarks:
Syntax in capitals are a thing from before the Cretaceous. Please don't burden our eyes, we have reading glasses for that.
Variants can be used in generics, BUT then you are doing something wrong. Generics are to defeat variants, amongst other.

zamtmn:
Thaddy
Are you sure that's the problem? I'm not.

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---  Writeln (sizeof(TRecord));  Writeln (sizeof(i.Key));returns the same values, regardless of $longstrings value

zamtmn:
TDictionary with key=record with longstring (or any data by pointer) can't work properly by design, use TMap or custom hash method

update:
it would be right to make a warning for such things

Thaddy:

--- Quote from: zamtmn on January 26, 2022, 02:39:07 pm ---Thaddy
Are you sure that's the problem? I'm not.

--- End quote ---
Yes, I am sure.

Navigation

[0] Message Index

[#] Next page

Go to full version