ProgramlamaC geliştirici

C dilinde hata işleme nasıl gerçekleştirilir? setjmp/longjmp, errno ve hata kodu döndürme arasındaki farklar nelerdir? Hangi durumda hangi yaklaşımı kullanmak gerekir?

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap

C dilinde yerleşik istisna desteği yoktur, hata işleme şu şekillerde gerçekleştirilir:

  1. Hata kodu döndürme (genellikle fonksiyonun dönüş değeri ile) Örnek:

    int read_file(const char *name) { FILE *f = fopen(name, "r"); if (!f) return -1; // Hata // ... fclose(f); return 0; // Başarı }
  2. Küresel değişken errno kullanımı Hata durumunda standart fonksiyonlar genellikle küresel errno değişkenini ayarlar. Örnek:

    FILE *fp = fopen("nofile", "r"); if (!fp) { perror("Dosya hatası"); // errno sebebi belirtir }
  3. setjmp/longjmp — "istisna" fırlatma mekanizması (çalışma bağlamı korunur ve geri yüklenir) Karmaşık durumlar için kullanılır (örneğin, farklı seviyelerde acil sonlandırma). Nadir kullanılır, çünkü kodu karmaşıklaştırır ve kaynak sızıntılarına yol açabilir.

    #include <setjmp.h> jmp_buf buf; if (setjmp(buf) == 0) { // ... longjmp(buf, 1); // setjmp(...)'e geri döner } else { // Hata işleme }
  • Hata kodu döndürme — esas yöntem, basit ve güvenlidir.
  • errno — kütüphane fonksiyonları için uygundur.
  • setjmp/longjmp — özgül durumlar için (karmaşık kütüphaneler veya yorumlayıcılar).

Hileli Soru

Aşağıdaki kod ne çıktıyı verir?

#include <stdio.h> #include <setjmp.h> jmp_buf buf; void func() { longjmp(buf, 5); } int main() { int val = setjmp(buf); printf("val=%d\n", val); if (val == 0) func(); return 0; }

Cevap:

  • İlk çağrıda setjmp 0 döndürür ve func fonksiyonu çağrılır.
  • Orada longjmp(buf, 5) gerçekleşir, yürütme setjmp'e geri döner, bu sefer 5 döndürür.
  • Nihai çıktı:
    val=0
    val=5
    

Gerçek Hata Örnekleri


Hikaye Bir kütüphanede hata durumunda temizleme mekanizması yalnızca hata kodu ile baştan sona manuel olarak uygulanmıştır. Ancak programcı, geri dönüş değeri setjmp/longjmp üzerinden bir callback'ten dönerken hatayı işlemekten unuttuğundan bellek sızıntıları ve dosya kilitlenmeleri oluştu.


Hikaye Bir ağ uygulamasında, socket işleminden sonra errno kontrolü atlandı. Bu, önceki fonksiyonun yanlış eski bir değeri nedeniyle yanlış teşhisle sonuçlandı.


Hikaye Ekip, çok sayıda hata kodu geri dönüş noktası ile karmaşık bir iç içe geçiş uyguladı ancak dönüş değerleri konvansiyonlarına (sıfır/negatif değerler) uyulmadı. Bazı hatalar başarı olarak yorumlandı, bu da hizmetin öngörülemeyen arızalarına yol açtı.