1 Aralık 2013 Pazar

C 'de Hata Ayıklama (Assert Makrosu)

Programlamanın en önemli kısımlarından biride hata ayıklama(debuging) bölümüdür. C 'de hata ayıklama işlemi için bize mükemmel olmasa da bizi idare edebilecek çoğu kişinin kullanmadığı bir makro ile gerçekleşmektedir. Öncelikle makrolar nelerdir daha özel adıyla function like macro(fonksiyon benzeri makro)'lar nelerdir onlara kısaca bir bakalım.

Fonksiyon Benzeri Makrolar(Function Like Macro) : Burada define komutlarını ve önişlemci(preprocessor) programı biliyormuşuz gibi anlatacağım. Function like macro 'lar da object like macro'lar gibi bir define komutu ile oluşturulur. Fonksiyonların çağırılmasındaki gibi bir maliyetleri yoktur. Sadece "bul-değiştir" işlemi ile derleme zamanından(compile time)'dan önce değiştirilirler. Derleyici(compiler) bu fonksiyon benzeri kodları görmez yerine geçenleri görür. Assert de fonksiyon değil makrodur. Bir örnekle gösterirsek.

#define       arraysize(a) (sizeof((a)) / sizeof(*(a)))  //dizinin size'ını bulan bir makro

bu durumda önişlemci arraysize(dizininadı) gördüğü yeri (sizeof((dizininadi)) / sizeof(*(dizininadi))) olarak değiştirecek.
NOT : parantezler operatör önceliğinden hata almamak için gerekli! Çünkü makro bir işlem içinde kullanılabilir.

Assert : Gelelim artık assert makrosuna bu makro kontrol durumlarında işimize yarayacak. Yani örneğin en basitinden 0'a bölme hatası yapmamak adına bu makroyu kullanabiliriz. Bu makro şöle çalışmaktadır.
assert(exp) yani assert(x != 0) gibi hata olabilecek durumlar assert makrosunun içine yazılır. Hata var ise ekrana hata mesajı yazar ( bu arada stderr 'e yazar) ve abort() fonksiyonunu çağırarak programı sonlandırır.

Peki debug işlemimiz bitti ve assert makrolarını koddan temizlemek zor geliyor. Bunu da düşünmüşler temizlemenize gerek yok. assert.h'nın include 'undan önce NDEBUG 'ı define eferseniz assert makroları yerine assert(ignore)((void) 0) yerleştirilecektir.

Bu nedenle assert içinde işlem yapmak sakıncalıdır. NDEBUG define edip assert'ü kaldırmak isterken kodu bozarız örnek olarak

int *ptr;
assert(ptr = (Tür*)malloc(sizeof(Tür)));

hatadır NDEBUG define edip alt kodlarda ptr kullanırsak ptr değer almadığından undefined behavior olur.

Bugünlükte yazımızın sonuna geldik umarım faydalı olmuştur. Bir hatam olduysa affola herkese iyi okumalar :)

Hiç yorum yok:

Yorum Gönder