27 Ekim 2009 Salı

C Dilinde Assertion

Bu yazımda sizlere C diliyle yazdığınız programlarda kullanabileceğiniz assert.h kütüphanesiyle gelen assert fonksiyonundan bahsedeceğim. Önce assert kelimesinin anlamını açıklayarak başlayalım.Bu fonksiyonda yaptığı işlev bağlamında assert; ısrar etmek,öne sürmek,bildirmek anlamlarına geliyor.Fonksiyonun prototipi şu şekilde:

void assert (int expression).

Parametre olarak bir karşılaştırma ifadesi ("data != NULL" gibi) alınıyor.Eğer bu ifadeki koşul sağlanıyo ise program normal çalışmasına devam ediyor.Koşul sağlanmadığı zaman ise programın çalışması bu satırda kesiliyor ve ekrana aşağıdaki gibi bir hata mesajı yazdırılıyor(stderr'a yazılıyor).



Assertion failed: data != NULL, file Assert.c, line 14

Programın çalışmasının bu sebepten kesilmesine ingilizce "assert violation" adı veriliyor. Bir "assert violation" ise bize programda bir bug olduğunun habercisi oluyor.Bu yüzden bu işlev, programların güvenilirliğini artırmak için sistematik bir debugging tool olarak kullanılabilir.

Bu tür fonksiyon çağrıları yaptığımız deyimler assertion deyimi olarak nitelendiriliyor..Bu deyimlerin 3 farklı kullanımı söz konusu.

1.Preconditions
2.Postconditions
3.Invariants

1.Preconditions:  Bir yazılım geliştirici(developer) tarafından yazılan fonksiyonlarda parametrelere kesin önkoşullar verilerek gerçekleştiren kullanımdır.Örneğin daha önceden rasgele biçimde seçilmiş zarların değerlerini yazdırmak için bir fonksiyon yazdığımızı düşünelim.

void zarlariYazdir(int zar1,int zar2)
{
    assert(zar1 > 0 && zar1 < 7);
    assert(zar2 > 0 && zar2 < 7);
   
    printf("zar1: %d zar2 : %d",zar1,zar2);
}

Zarların rasgele seçimi için yazılmış kod parçasının bu seçimi 1 ve 6 arasındaki tamsayı değerlerden gerçekleştirmesi gerektiğini ve bunun dışındaki bir durumun da bug olacağını öngörebiliriz. Öyleyse, zarlariYazdir adını verdiğimiz bu fonksiyonda zar1 ve zar2 değerlerinin bu aralıkta olmasını zorlayabiliriz. zarlariYazdir  fonksiyonu çalışmaya başladığında eğer zarlar 1-6 aralığında değillerse programın çalışması durdurulacak (abortion via assert violation) ve bize bir bug ı teşhis etme şansı sunacaktır.

2.Postconditions : Bu kullanım ise genelde herhangi bir fonksiyonun döndüreceği değerin doğruluğunu zorlamak için kullanılır.Örneğin dizilerle ilgili bir işlem yaptığımızı ve fonksiyonun sonunda hesaplanmış bir index değerini döndüreceğimizi düşünelim. Bu hesaplanan index değerinin geçerli bir değer olması için LENGTH dizinin boyu olmak üzere [0,LENGTH) aralığında olması gerekir.Bu koşulu zorlayan bir assertion deyimi aşağıdaki gibi yazılabilir.

    ...
    assert(index >= 0 && index < LENGTH);
    return index;
 }


Postcondition kullanım türü genelde preconditions kullanım türüne göre çok daha azdır.Preconditions türü kullanımda ise en çok kullanılan ve en işlevsel deyimler ise genelde

    * pointer'ların NULL olmaması gerektiğini veya
    * index ve boy değerlerinin negatif olmaması ve limit değeri aşmaması gerektiğini

zorlayan deyimlerdir.Pointer ile kullanımına aşağıdaki gibi bir örnek verilebilir.

void veriyiYazdir(data* currentData)
{
    assert(currentData != NULL);
    printf("%d %d",currentData->sayi1,currentData->sayi2);
}

Assertion deyimlerine fonksiyonla ilgili açıklama satırlarında yer verilmesi güzel bir alışkanlıktır.Örneğin zarlariYazdır fonksiyonu için aşağıdaki gibi bir standartta açıklama satırı yazılması gerekir.


/*  Asserts:
*      'zar1' is between [1,6]
*      'zar2' is between [1,6]
*/
 
Assert deyimi programlarda bug tespiti için kullanılabilecek güzel bir araçtır.Ancak, bug ve çalışma zamanı hatası kavramları birbiriyle karıştırılmamalıdır.Örneğin bir menüde kullanıcının yanlışlıkla gireceği negatif bir değer bir çalışma zamanı hatasıdır.Böyle bir hata ile karşılaşıldığında programın sonlandırılmasındansa hatalı giriş yaptığını kullanıcıya bildirip yeni bir değer istemek en makul çözümdür.Bu yüzden bu senaryo alışılagelmiş kontrol deyimleriyle (if-else,switch) çözülmeli, başka bir deyişle assert deyimi ile gerçekleştirilmemelidir. Ancak, elbette yalnızca çalışma zamanında karşılabileceğimiz buglar da olabilir.Bu durum göz önüne alındığında hangi durumların assert deyimiyle hangi durumlarınsa klasik kontrol deyimleriyle ele alınacağı geliştiricinin tasarımına kalmıştır.
 
Ayrıntılı bilgi için kaynaklar:
http://www.cplusplus.com/reference/clibrary/cassert/assert/
http://ptolemy.eecs.berkeley.edu/~johnr/tutorials/assertions.html

2 yorum:

  1. Cok iyi hocam:) bir de javada unit testlere el atsaniz super olacak.. devamini bekliyoruz.

    YanıtlaSil
  2. Teşekkür ederim Emre :) beğendiğine sevindim.Ona da el atarım yakında inşallah.Değişik konularda daha sık yazmaya devam edeceğim ;)

    YanıtlaSil

 
Web Analytics Page copy protected against web site content infringement by Copyscape Software Blogs - BlogCatalog Blog Directory