XE8にアップグレードした後、いくつかのプロジェクトはデータを破壊し始めます。 TList実現のバグのようです。
program XE8Bug1;
{$APPTYPE CONSOLE}
uses
System.SysUtils, Generics.Collections;
type
TRecord = record
A: Integer;
B: Int64;
end;
var
FRecord: TRecord;
FList: TList<TRecord>;
begin
FList := TList<TRecord>.Create;
FRecord.A := 1;
FList.Insert(0, FRecord);
FRecord.A := 3;
FList.Insert(1, FRecord);
FRecord.A := 2;
FList.Insert(1, FRecord);
Writeln(IntToStr(FList[0].A) + IntToStr(FList[1].A) + IntToStr(FList[2].A));
end.
このコードは、XE7以前では(本来あるべきことですが)「123」を出力しますが、XE8では「120」を出力します。多分誰かがこれのクイックフィックスを知っていますか?
更新:非公式の修正は ここ
私の場合、TList<T>.Insert
メソッド呼び出しTListHelper.InternalInsertX
はデータサイズに依存することがわかりました。
procedure TListHelper.InternalInsertN(AIndex: Integer; const Value);
var
ElemSize: Integer;
begin
CheckInsertRange(AIndex);
InternalGrowCheck(FCount + 1);
ElemSize := ElSize;
if AIndex <> FCount then
Move(PByte(FItems^)[AIndex * ElemSize], PByte(FItems^)[(AIndex * ElemSize) + 1], (FCount - AIndex) * ElemSize);
Move(Value, PByte(FItems^)[AIndex * ElemSize], ElemSize);
Inc(FCount);
FNotify(Value, cnAdded);
end;
最初のMove
呼び出しで問題が発生しました。宛先は次のとおりです。
PByte(FItems^)[(AIndex + 1) * ElemSize]
ない
PByte(FItems^)[(AIndex * ElemSize) + 1]
アーグ!
最後に、プロジェクトでDelphi XE7のSystem.Generics.Defaults.pasユニットとSystem.Generics.Collections.pasユニットを使用しましたが、すべて期待どおりに機能するようになりました。
更新:私が見るように、RTLは影響を受けません。SizeOf> 8のTにTList<T>.Insert
を使用しないためです(または何かを見逃している可能性がありますか?)