Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TStringList - odd behavior

Tags:

delphi

Delphi 1 16-bit (yeah it's old, but it works well)

Some sample code:

procedure TForm1.Button1Click(Sender: TObject);
var
  SL: TStringList;
begin

  SL := TStringList.Create;
  SL.Sorted := True;
  SL.Duplicates := dupIgnore;

  SL.AddObject('A', TObject(100));
  SL.AddObject('A', TObject(999));
  ShowMessage(IntToStr(LongInt(SL.Objects[0]))); {A}

  SL.Free;

end;

I'm using the Object field to store longints (a hack, yes but it gets the job done). Anyway, at line A above I would expect ShowMessage to show 100, instead it shows 999 (even if dupIgnore is set). Am I missing something here? Or should it work this way (I expected the stringlist to ignore the 999)?

like image 884
FrankCM Avatar asked Nov 01 '10 16:11

FrankCM


2 Answers

Just tested in Delphi 2009 - it shows 100 (and it should show 100 according to the Delphi 2009 documentation about Duplicates and dupIgnore).

Probably it is Delphi 1 bug.


Updated

@Sertac Akyuz: Yes, that seems to be true. Google shows that old Delphi versions had the following implementation of TStringList.Add and TStringList.AddObject methods:

function TStringList.Add(const S: string): integer;
begin
  if not Sorted then
    Result := FCount
  else
    if Find(S, Result) then
      case Duplicates of
        dupIgnore: Exit;
        dupError: Error(SDuplicateString, 0);
      end;
  InsertItem(Result, S);
end;

function TStrings.AddObject(const S: string; AObject: TObject): Integer;
begin
  Result := Add(S);
  PutObject(Result, AObject);
end;

The current (Delphi 2009) implementation is:

function TStringList.Add(const S: string): Integer;
begin
  Result := AddObject(S, nil);
end;

function TStringList.AddObject(const S: string; AObject: TObject): Integer;
begin
  if not Sorted then
    Result := FCount
  else
    if Find(S, Result) then
      case Duplicates of
        dupIgnore: Exit;
        dupError: Error(@SDuplicateString, 0);
      end;
  InsertItem(Result, S, AObject);
end;

See the difference. The old implementation may be viewed as a bug (memory leak, etc) or an undocumented allowed behavior. In any case the current implementation is free from the problem.

like image 90
kludg Avatar answered Oct 09 '22 13:10

kludg


You're not missing anything. That's exactly what happens.

AddObject starts by calling Add, which returns the index of the new (or existing) element in the list. Then it calls PutObject to assign the object value at that index. Behavior with respect to the Duplicates property is not specified in the documentation.

like image 35
Rob Kennedy Avatar answered Oct 09 '22 15:10

Rob Kennedy