C dilinde hata işlemesi her zaman geliştiricinin görevi olmuştur. Standart kütüphanede istisnalar yoktur, hatalar dönüş kodları veya global değişken errno ile döndürülür (kullanım başlangıcı - 1970'lerin UNIX'i, ardından POSIX ve ANSI C). Bu mekanizmalar, olağandışı durumlarda yürütme akışını yönetmek için günümüzde de kullanılmaktadır.
Standart fonksiyonlarla (dosya işlemleri, bellek tahsisi, dize fonksiyonları) çalışırken hatalar özel bir kontrol olmadan fark edilmeyebilir. Yanlış işleme - dönüş kodunu yok saymak, errno'yu yanlış yorumlamak, kaynakları temizlememek - programın yanlış çalışmasına, çökmesine ve güvenlik açıklarına neden olur.
Hataların doğru işlenmesi, dönen değerlerin zorunlu olarak analiz edilmesini, errno'nun yalnızca hata durumunda kullanılmasını ve hataların bilgilendirici bir şekilde çıktısını gerektirir. Dönüş kodları, iç fonksiyonlar için tercih edilir - global yan etkilere neden olmadan işleme yapılmasına olanak tanır. errno genellikle sistem çağrıları ve standart kütüphane fonksiyonları ile birlikte kullanılır. Her potansiyel olarak tehlikeli işlemin ardından dönüşü analiz edilir ve global durum (errno) ara çağrılarla silinmemelidir.
Kod Örneği:
#include <stdio.h> #include <errno.h> #include <string.h> FILE *open_file(const char *filename) { errno = 0; FILE *f = fopen(filename, "r"); if (!f) { fprintf(stderr, "Hata: %s ", strerror(errno)); } return f; }
Ana Özellikler:
Kullanıcı fonksiyonları için errno kullanmak mümkün mü, eğer hataları yukarı iletmek istiyorsak?
Hayır, errno yalnızca standart kütüphane ve sistem çağrıları için tasarlanmıştır. Globaldir, herhangi bir noktada yeniden yazılabilir ve kendi fonksiyonlarınız için uygun değildir.
Her fonksiyon çağrısından önce errno ayarlamak zorunlu mu?
Hayır, ancak değişikliklerin analiz edileceği düşünülüyorsa errno'yu (örneğin sıfıra) sıfırlamak önerilir. Her fonksiyon başarı durumunda errno'yu değiştirmez, yalnızca hata durumunda değiştirir.
errno = 0; ... tehlikeli fonksiyon çağrısı ...
Herhangi bir fonksiyondan sonra errno'ya güvenmek mümkün mü?
Sadece standartta açıkça başarısızlık durumunda atanmış olan fonksiyonlar için. Standart kütüphane fonksiyonlarının çoğu başarı durumunda errno'yu etkilemez. Dokümantasyon - dostunuzdur.
Sonucu kontrol etmeden bir dosya açmak, hatalar analiz edilmez, dosya yok olduğunda program yanlış çalışır:
Artılar:
Eksiler:
Her kritik fonksiyondan sonra sonuç kontrol edilir, hata durumunda errno ile detaylı bir hata mesajı döndürülür, işlem doğru bir şekilde sona erdirilir:
Artılar:
Eksiler: