-O2 -O3 -O4 The compiled program will trigger abnormal access
This problem is extremely strange. As long as the -O2 -O3 -O4 optimized compilation option is not turned on, or the TStrItems defined by the generic type are not used, everything works fine.
Once the optimization option is turned on, and TStrItems are defined using generics, an exception will appear. I guess the optimization compile generated the wrong optimization code.
I tested windows x86_64, linux aarch64 and all had the same problem
Here is the code that can reproduce the problem
program Project1;
{$MODE DELPHI}{$H+}
uses
{$IFDEF UNIX}
cthreads,
{$ENDIF}
SysUtils,
Classes,
Generics.Collections;
type
TStrItems = TList<string>; // If this definition is used, an exception will be triggered when the program executes
//TStrItems = TStringList; // If this definition is used, there will be no exceptions
{ TTestList }
TTestList = class
private
FStrs: TStrItems;
function GetStrs(out AStrs: TStrItems): Boolean;
function GetItem(I: Integer): string;
public
constructor Create;
property Items[I: Integer]: string read GetItem;
end;
{ TTestList }
function TTestList.GetStrs(out AStrs: TStrItems): Boolean;
begin
AStrs := FStrs;
Result := (AStrs <> nil);
end;
function TTestList.GetItem(I: Integer): string;
var
LStrs: TStrItems;
begin
// Logically, the GetStrs function must return false, and LStrs must be nil.
// If the - O2, - O3, or - O4 compilation options are not added, the generated program will not have any problems
// Otherwise, the generated program executing here will trigger an exception for illegal access
if GetStrs(LStrs) and (I >= 0) and (I < LStrs.Count) then
Result := LStrs[I]
else
Result := '';
end;
constructor TTestList.Create;
begin
FStrs := nil;
end;
var
LTestList: TTestList;
LTestStr: string;
begin
Writeln('111');
LTestList := TTestList.Create;
try
Writeln('222');
LTestStr := LTestList.Items[0];
finally
FreeAndNil(LTestList);
end;
Writeln('DONE');
end.
Edited by Yong Zeng