ilginç bir hata ama Neden?

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
Kullanıcı avatarı
muskut
Kıdemli Üye
Mesajlar: 1118
Kayıt: 22 Ara 2003 09:50
Konum: Sandalyemden
İletişim:

ilginç bir hata ama Neden?

Mesaj gönderen muskut »

S.A.

Geçmişte yaşanmış çok ilginç bir hata nakledecem size :) İki gün önce bir kod yazdım iç içe döngü kullanıyordum. Örneğin bi döngü şu:

i := 0;
For i := 0 to 2 do
begin
Dizi[i+2] := 3;
end;

Bilin bakalım burda ki hata ne? :) Bu bizim delfi, uzun arayışlar sonucu, bize şunu demek istediğini anladım. Programı derliyorum. i'nin değerini döngüden önce 0 atamama rağmen 43234 gibi bi değer dönderiyor. Hadi onu geçtim dizi başlarken i'nin başlangıcını -3 alıyor, hadi onuda geçtim, delfi diyorki; Sen bu döngüyü hiç kullanmadığından dolayı bu döngü silinmiştir. :) 2 gündür kafayı sıyırttı. Aynı kodu açıyorum başka formda, başka makinada, başka evde yazıyorum banamısın demiyo :) Sonunda hatayı şöyle düzelttik:

i := 0;
For i := 0 to 2 do
begin
Dizi[i+2] := 3 + ( i - i );
end;

Bunu yazınca, ( i - i ), delfi anladıkı i kullanılıyor ve bu sefer doğru işlemleri yapmaya başladı. Benim delfi ile birlikteliğim çoz uzun sürelere dayanmıyor. Ama uzun yıllardır delfi ile uğraşmış arkadaşım bile bu güne kadar böyle bir hata ile karşılaşmadığını söyledi. Nedir bu delfinin sorunu, pilen far mı?
Kullanıcı avatarı
Kuri_YJ
Moderator
Mesajlar: 2248
Kayıt: 06 Ağu 2003 12:07
Konum: İstanbul
İletişim:

Mesaj gönderen Kuri_YJ »

Selamlar,

Delphi'nin derleyicisinin kökenleri Pascal'a kadar dayanır. Aslında Borland'ın hemen hemen tüm derleyicilerinde kod oprimizasyonu vardır ve kodu okuduktan sonra eğer hiç kullanılma ihtimali olmayan kodları derleyici otomatik olarak EXE'den çıkarır.

Şimdi şöyle bir kod yazarsanız

Kod: Tümünü seç

Procedure DENEME(intX : Integer) ;
Var
  intI : Integer ;
Begin
  intI := 0 ;
  For intI := intX To intX+10 Do
  Begin
   // Ivır Zıvır İşlemler ;
  End
End ;
Yukarıdaki kodda ilk olarak intI := 0 satır kod optimizasyonunda koddan atılır. Zira İki defa aynı değişkene atama yapılıyor. Ve bu atamalar arasında değişken hiç kullanılmıyor. Zaten derlemelerde Hint ve Warningler bu tür gereksiz kullanımları veya hata ihtimali oluşturabilecek kodların uyarısında bulunur.

Borland'ın derleyicileri SÜPER'dir. Eski zamanlarda (94 Senesiydi) Scrolling Star Field Intro'su hazırlarken, adresler arası taşıma işlemi yapıyorduk ve bazı hesaplamalar filan, neyse hızı bize biraz yavaş geldi bu işlemlerin. Oturup Assembler'da yazalım, Pascal'a o source yapıştıralım dedik. Ama öncesinde EXE'den debug edip, Pascal'ın nasıl yaptığına bir göz atalım, eğer hızlandırabileceğimiz bir şey varsa müdahale edelim dedik. Bizim yazdığımız Assembler komutlar yaklaşık 20 satır kadar tutuyordu. EXE'yi debug ettiğimizde derleyicinin bu işlemi aslında 4-5 satıra indirgeyip yaptığını görünce Gözlerimiz yuvalarından fırladı.

Ayrıca ek bilgi olarak söyleyim,

Kod: Tümünü seç

  If (intA = 0) And (intB = 10) And (intC > 50) Then
  Begin
    // Ivır Zıvır
  End ;
Yukarıdaki gibi birkaç OR veya AND komutlarında Borland Harika optimizasyonlar yapıp, assemblerda yazdığınız IF'i minimum CPU Cycle'ı harcayacak şekilde düzenliyor. Yani program Eğer intA'ya atanan değer 0 (Sıfır) değil ise, doğrudan geri Jump ediyor ve Hiç diğer karşılaştırmaları yapmıyor. Yani tek kelime ile HARİKA 8) . Aynı işlemi VB'de yaparsanız, VB bütün If'teki adımların hepsini yapar ve sonra karar verir. (Her nasıl karar veriyorsa bazen kendi insiyatifini kullanıp olumsuz durumlarda bile IF'e girebiliyor, yada tam tersini yapıp, tüm şartlar okey olsa bile girmemekte inat edebiliyor. Tecrübe ile sabittir :lol:

Muhtemelen sizin kodlarınızın bütünlüğünde veya çağrıldığı noktalarla ilgili sıkıntıları vardır bu sebeple kodu beğenmemiştir.

Bence kodu bir daha gözden geçirip kontrol edin eminim HINT ve Warningler verecektir.

Kolay Gelsin.
Kuri Yalnız Jedi
Harbi Özgürlük İçin Pisi http://www.pisilinux.org/
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4741
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Mesaj gönderen mrmarman »

Selam...

- Bana da ilginç geldiğinden aşağıdaki şekilde bir buton procedure kurgusu yaptım... Ama hata ile karşılaşmadım.. Aynı kodu sen de dener misin ?

Kod: Tümünü seç

Var
  i : Integer;
  Dizi : Array[0..10] of Array [0..10] of Integer;
begin
  i := 0; // buna gerek yok ama sen yazdın diye silmedim...
  For i := 0 to 2 do
  begin
    Dizi[i][i+2] := 3;
    ShowMessageFmt('%d, %d : %d', [i, i+2, Dizi[i][i+2]]); // her aşamada alınan değeri görüyoruz...
  end;
end;
Resim
Resim ....Resim
Cevapla