SORU
13 EKİM 2011, PERŞEMBE


Örtülü arayüzü değişkenler derleyici tedavi belgelenmiştir?

Örtülü arayüzü değişkenler hakkında question benzer bir çok uzun zaman önce sormuştum.

Bu sorunun kaynağı benim kodunda bir hata nedeniyle bana örtülü bir arabirim değişken derleyici tarafından oluşturulan varlığından haberdar değil. Bu değişken, buna ait prosedürü bittiğinde tamamlanmıştır. Bu da bir hata değişkeni beklediğimden daha uzun olan ömrü nedeniyle.

Şimdi, derleyici bazı ilginç davranış göstermek için basit bir proje var:

program ImplicitInterfaceLocals;

{$APPTYPE CONSOLE}

uses
  Classes;

function Create: IInterface;
begin
  Result := TInterfacedObject.Create;
end;

procedure StoreToLocal;
var
  I: IInterface;
begin
  I := Create;
end;

procedure StoreViaPointerToLocal;
var
  I: IInterface;
  P: ^IInterface;
begin
  P := @I;
  P^ := Create;
end;

begin
  StoreToLocal;
  StoreViaPointerToLocal;
end.

StoreToLocal tahmin edebileceğiniz gibi derlendi. Yerel değişken I, işlevin sonuç, Create var örtülü bir parametre olarak geçirilir. StoreToLocal için düzenli IntfClear tek bir çağrı olur. Pek sürpriz olmadı.

Ancak, StoreViaPointerToLocal farklı tedavi edilir. Derleyici 12* *geçirir örtülü yerel bir değişken oluşturur. Create döner, P^ atama yapılır. Bu iki yerel Değişkenler ile rutin arabirimi başvurular holding bırakır. İki StoreViaPointerToLocal derli toplu sonuçları 16 ** çağırır.

StoreViaPointerToLocal için derlenmiş kod şöyle:

ImplicitInterfaceLocals.dpr.24: begin
00435C50 55               push ebp
00435C51 8BEC             mov ebp,esp
00435C53 6A00             push $00
00435C55 6A00             push $00
00435C57 6A00             push $00
00435C59 33C0             xor eax,eax
00435C5B 55               push ebp
00435C5C 689E5C4300       push $00435c9e
00435C61 64FF30           push dword ptr fs:[eax]
00435C64 648920           mov fs:[eax],esp
ImplicitInterfaceLocals.dpr.25: P := @I;
00435C67 8D45FC           lea eax,[ebp-$04]
00435C6A 8945F8           mov [ebp-$08],eax
ImplicitInterfaceLocals.dpr.26: P^ := Create;
00435C6D 8D45F4           lea eax,[ebp-$0c]
00435C70 E873FFFFFF       call Create
00435C75 8B55F4           mov edx,[ebp-$0c]
00435C78 8B45F8           mov eax,[ebp-$08]
00435C7B E81032FDFF       call @IntfCopy
ImplicitInterfaceLocals.dpr.27: end;
00435C80 33C0             xor eax,eax
00435C82 5A               pop edx
00435C83 59               pop ecx
00435C84 59               pop ecx
00435C85 648910           mov fs:[eax],edx
00435C88 68A55C4300       push $00435ca5
00435C8D 8D45F4           lea eax,[ebp-$0c]
00435C90 E8E331FDFF       call @IntfClear
00435C95 8D45FC           lea eax,[ebp-$04]
00435C98 E8DB31FDFF       call @IntfClear
00435C9D C3               ret 

Derleyici bunu neden yapıyor olduğunu tahmin edebiliyorum. Sonuç değişken atama bir istisna (Yani eğer değişken bir yerel) çıkarmayacaktır o zaman kanıtla o zaman sonuç değişkeni doğrudan kullanır. Aksi takdirde bir istisna durumunda başvuru kaçak değiliz böylece sağlanması döndüğünde örtülü ve yerel bir kopya arabirimi kullanır.

Ama ben bu belgelerinde herhangi bir açıklamada bulun. Arayüz ömür boyu önemlidir çünkü önemli ve bir programcı olarak etki edebilmek vesileyle gerekir.

Kimse bu davranışın herhangi bir belge olup olmadığını biliyor mu? Herkes herhangi bir daha fazla bilgi var mı? Nasıl örnek alanlar işlenir, henüz kontrol etmedim. Tabii ki kendim için deneyebilirim ama daha resmi bir açıklama arıyorum ve her zaman uygulama detay deneme yanılma ile çalıştım güvenerek önlemek için tercih.

Güncelleme 1

Remy bu soruyu cevaplamak için, başka bir sonlandırma yapmadan önce arayüz arkasındaki nesneyi tamamlamak için ihtiyacım olduğunda benim için önemliydi.

begin
  AcquirePythonGIL;
  try
    PyObject := CreatePythonObject;
    try
      //do stuff with PyObject
    finally
      Finalize(PyObject);
    end;
  finally
    ReleasePythonGIL;
  end;
end;

Böyle yazılı olarak iyi. Ama gerçek kod GİL yayımlandıktan sonra kesinleşmiş olan ve bombaladılar ikinci örtülü bir yerel kaldım. İçeride kodu ayrı bir yönteme/Yayın GİL Elde çıkartarak sorunu çözdüm ve böylece arayüzü değişken kapsamı daralmış.

CEVAP
11 Kasım 2013, PAZARTESİ


Eğer bu davranış herhangi bir belge varsa, muhtemelen parametre olarak fonksiyon sonuçları geçirerek geçici değişken derleyici üretim Ara sonuçları tutmak için alanında olacak. Bu kodu göz önünde bulundurun:

procedure UseInterface(foo: IInterface);
begin
end;

procedure Test()
begin
    UseInterface(Create());
end;

Derleyici Useİnterface içine arabirimi bir ömür boyu ^ olduğundan emin olmak için geçirilen Oluşturmak sonucunda tutmak için örtülü geçici bir değişken oluşturmak için . = Useİnterface ömrü arayın. Örtülü temp değişkeni Test sonunda bu durumda, onun sahibi olan prosedür sonunda bertaraf olacağını() yordamı.

İşaretçi atama davanızı Ara arabirimi geçen derleyici "" değeri nereye gidiyor göremiyorum. beri olarak işlev parametre değerleri, aynı kova içine düşmek olabilir.

Yıllar içinde bu alanda bir kaç hata var hatırlıyorum. Uzun zaman önce (D3? ) D4?, derleyici Ara değer referans sayılmaz. Çoğu zaman işe yaradı ama parametre diğer durumlarda başı derde girdi. Bir sabit parametreler ile ilgili takip hitaben bir zamanlar, inanıyorum. Orada her zaman bir arzu taşımak bertaraf Ara değeri arabirim, bir an sonra deyim hangisi gerekli, ama sanmıyorum ki hiç gerek uygulanan win 32 iyileştirici çünkü derleyici değildi ayarlamak için işleme emrinde deyim veya blok parçalı yapı.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Dave Wallace

    Dave Wallace

    27 Kasım 2007
  • Glyn Dewis

    Glyn Dewis

    25 AĞUSTOS 2007
  • jbignacio

    jbignacio

    13 Mart 2006