2015-04-27 15 views
38

XE8'e yükselttikten sonra bazı projelerimiz veriyi kırmaya başladı. TList realizasyonda bir hataya benziyor.TList <T>'daki Delphi XE8 hatası, geçici çözüm gerekiyor

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. 

Bu kod yazdırılır XE7 içinde "123" ve daha önce (olması gerektiği gibi), ancak XE8 o "120" basar. Belki birisi bunun için bir ipucu biliyor mu?

Güncelleme:

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; 

İlk Move sorunu bkz: resmi olmayan düzeltme here

+9

jenerik koleksiyonları XE8 yeniden uygulanmıştır. Belki de Emba'da herhangi bir birim testi yoktur. Tanımladığınız buysa ve çözüm muhtemelen XE7'de kalmaktır. Bir hata raporu göndermeniz gerekiyor. –

+3

[Regression: TList .Insert çalışmıyor] olarak bildirildi (https://quality.embarcadero.com/browse/RSP-10773). –

+10

Yani Embarcadero'nun etkili bir test rejimi yok gibi görünüyor. Yeryüzünde bu yanlış nasıl olabilir? Böyle temel bir sınıf. İyi çalışan bir dev ekibin birimi kapsamlı bir şekilde test ederdi. Böyle bir hata asla bu testi geçmemelidir. Kasvetli. –

cevap

32

Şimdi TList<T>.Insert yöntem çağrısı TListHelper.InternalInsertX benim durumumda, veri büyüklüğüne bağlıdır bulmuştur olduğunu aramak. Hedef olmalıdır:

PByte(FItems^)[(AIndex + 1) * ElemSize] 

değil

PByte(FItems^)[(AIndex * ElemSize) + 1] 

Aaargh!

Son olarak, Projelerimdeki Delphi XE7'den System.Generics.Defaults.pas ve System.Generics.Collections.pas birimlerini kullandım ve şimdi her şey beklendiği gibi çalışıyor.

Güncelleme: Anlıyorum gibi olan T TList<T>.Insert kullanmaz olduğu gibi, RTL, etkilenmez sizeof> 8 (ya da belki bir şeyler kaçırmak?)

+0

Yöntemi yerinden oynatın ve devam edin. –

+3

XE7 uygulamasını geri yükleyerek düzeltme yapmak o kadar da kötü bir fikir değil. Daha fazla güvenin var. Evet, bu bir yöntemi yayabilirsin ama başka neyin yanlış olduğunu merak etmiyor musun? –

+1

Tüm üniteleri değiştirseniz de, RTL/VCL/FMX vb. Anlamına gelen bir şekilde sabit üniteleri de kullanmanız akıllıca olacaktır. Aksi halde, bu kusurun diğer belirtileri tarafından incinebilir. –

İlgili konular