Program yazarken karşılaştığım sorunların %10 gibi bir bölümü gcc nin optimizasyon bugları 
Daha doğrusu , gcc , sonucunu kullanmayacağımızı düşünüp, kod içinde yap dediğimiz bir çok şeyi yapmayabiliyor.
Örneğin boş bir fonksiyon çağırdığımızda ne de olsa bir iş yapmıyor diye fonksiyona hiç girmiyor, ya da fonksiyon her daim 5 değerini döndürüyor ve biz bu değeri ekrana yazıyorsak, fonksiyona girip dönüş değerini alacağına printf e kendisi 5 veriyor ve ekrana yazdırıyor 
Kulağa hoş gelse bile bu özellikler bazen çok canımı sıkıyor. Şimdi size vereceğim şu küçük kodu Dev C++ ile dediğim gibi çalıştırırsanız ne demek istediğimi anlayacaksınız. Ya da Gcc .... -O3 şeklinde çalıştırabilirsiniz konsoldan.
Bilindiği gibi C de fonksiyon çağırmanın bazı usülleri vardır. Örneğim _cdecl _stdcall _pascal gibi fonksiyon çağırma yöntemi vardır.
Bu yöntemlerin birbirinden farkı, fonksiyona parametreler hangi sırada atılacak ve stack i fonksiyon mu toparlayacak vs.
Dev C++ ı en iyi optimizasyona ayarlayarak kodumu yazıyordum, ancak fonksiyon yapması gereken işi yapmıyor adeta saçmalıyordu. Önce dizilerden birisi taşıp fonksiyon parametrelerini mi değiştirdi diye düşündüm ama öyle olsa daha önce gelen fonksiyonun dönüş adresi de değişmeliydi. Halbuki fonksiyona giriyordu ama hatalı sonuç üretiyordu.
Daha sonra hatanın kaynağını tespit edip en temel haliyle göstereyim dedim. Aşağıda verdiğim kodu çalıştırmadan önce Dev C++ da araçlar-derleyici ayarları-kod-optimizasyon-diğer optimizasyon-en iyi optimizasyon bölümünü yes yapın.

Daha sonra aşağıdaki kodu çalıştırın. Bendeki ekran görüntüsünü de koyuyorum...
PHP Kodu:
#include <stdio.h>
int fonksiyon (int x,int y,int z ){
// printf(" %X %X %X\n\n",&x,&y,&z);
printf(" Birinci parametre adres : %X | deger : %X\n", &x, *(&x));
printf(" ikinci parametre adres : %X | deger : %X\n", &x+1,*(&x+1));
printf(" Ucuncu parametre adres : %X | deger : %X\n", &x+2,*(&x+2));
printf("\n Geri donus degeri %X\n",*(&x-1));
return x+y+z;
}
int main(){
int i;
i=fonksiyon(0x50,0x60,0x70);
getch();
return 0;
}

Aslında x parametresinin adresinde 50h değeri varken y parametresinde 60h z parametresinde ise 70h değeri olması gerekiyordu. Ayrıca x parametresi stack e atılamdan önce geri dönüş değeri atılacağından &x-1 adresinde ise fonksiyonun geri dönüş değeri olması gerekiyordu.
Tabi her zaman yaptığım gibi optimizasyonu kapatarak kodu tekrar derleyim dedim, sonucu tahmin ediyorsunuz. Deminki yes yaptığınız bölümü no yapıp kodu tekrar derleyelim..

Gördüğünüz üzre fonksiyon taş gibi çalışıyor. Peki optimizasyon durumunda Gcc bunu neden yapıyor??
Çünkü kodu kısaltmak ve hızlandırmak adına, _cdecl fonksiyon çağırma standartını bile eziyor, bizim parametrelere bu adreslerden erişmediğimizi düşünüp, onları istediği atreslere atıyor, ancak bizim o adresleri görmek istediğimizi anlarsa o zaman parametreleri doğru adreslere taşıyor.
Bunun ispatı için öncelikle tekrar Dev C++ ı en iyi optimizasyona alıyoruz, demin gösterdiğim yerden tekrar yes deyin. Şimdi kodu derlemeden önce // printf(" %X %X %X\n\n",&x,&y,&z); satırını tekrar açın, ben o satırı derlenmemek üzere yorum satırı haline getirmiştim, tek yapmanız gereken baştaki // yı kaldırmak.
Şimdi program bizim bu nesnelerin adreslerini görmek istediğimiz anlıyor ve parametreleri adreslere standartlara göre diziyor. Böylelikle bizim kodumuz da doğru çalışıyor.

Evet olay böyle cereyan ediyor, bu işlemleri linux da ya da konsolda yapmak için derleyicide kodu önce gcc ... şeklinde sonra da -O3 parametresi ile ayrı ayrı derlemelisiniz.
Bookmarks