David U
David U

Reputation: 993

Delphi: Code eliminated by linker incorrectly

I'm using Delphi 10.2. I'm having a problem calling TList<>.Last. The Evaluate window tells me the code for the function has been eliminated by the linker.

The code snippets:

uses
    ModelObjects,
    ProximitySearch,
    System.Classes,
    System.UITypes,
    System.Generics.Collections,
    Winsoft.FireMonkey.FPdfView,
    Winsoft.FireMonkey.PDFium;
...

type
    TWidgetFinder = class(TObject)
private
        fFieldInfos: TList<TFieldInfo>;
        fPAnnotation: FPDF_ANNOTATION;
...

procedure TWidgetFinder.ConfigureFieldInfo;
var
    key: String;
    buffer: TBytes;
    textLen: LongWord;
    temp: String;
begin
...
    SetLength(buffer, KShortBufferLength);
    textLen := FPDFAnnot_GetStringValue(fPAnnotation, ToStringType(key), buffer, Length(buffer))
    temp := TEncoding.Unicode.GetString(buffer, 0, textLen - 2);
    fFieldInfos.Last.Name := TEncoding.Unicode.GetString(buffer, 0, textLen - 2);
...

The problem was fFieldInfos.Last.Name was empty. I thought I was not converting the buffer to a string correctly. But the correct string is written to temp. When I Evaluate fFieldInfos.Last.Name after assigning to it I get the following message:

Function to be called, {System.Generics.Collections}TList<ModelObjects.TFieldInfo>.Last, was eliminated by linker

I've seen the SO solutions that suggest I call the eliminated function innocuously during initialization. But it cannot be that Delphi is eliminating code randomly and I must discover each elimination as a bug. I don't understand what I have done that tells the linker TList<>.Last is not being used when I am clearly using it. Can someone help me understand this?

Thanks

Upvotes: 0

Views: 2289

Answers (1)

Stefan Glienke
Stefan Glienke

Reputation: 21713

TList<T>.Last is a function marked as inline. Such methods usually are not contained in the binary so you cannot use them in the evaluator during debugging. The same is the case most likely if you type fFieldInfos[fFieldInfos.Count-1] because GetItem (the getter behind the index property) is marked as inline as well.

What you can type into the evaluator though is fFieldInfos.List[fFieldInfos.Count-1] to get the last item in the list.

P.S. As for the issue of Name being empty - if TFieldInfo is a record that assignment is not going to work because .Last will return a copy of that record and assign Name to that one not affecting the one inside the list.

Upvotes: 2

Related Questions