C dilinde tam sayı tipleri ile yapılan aritmetik işlemler, sonuç tipin temsil edilebilir aralığını aştığında taşmaya (overflow) yol açabilir, örneğin, int veya unsigned int. Taşma durumunda davranışın özelliği dilin standartlarıyla belirlenir.
İşaretli tiplerle (signed overflow) taşma, belirsiz davranışa (undefined behavior) yol açar, yani derleyici herhangi bir eylemi gerçekleştirme hakkına sahiptir: hatayı göz ardı etmek, bir istisna oluşturmak veya tahmin edilemez bir sonuç bırakmak. C standardına göre işaretsiz tiplerde (unsigned) taşma durumu tanımlıdır: tipin boyutuna göre modulo sıfırlanır (wraparound).
Unsigned sayılar için taşma sonucu kolayca tahmin edilebilir, örneğin, UINT_MAX + 1 == 0. İşaretli sayılar için ise, işlemlerden önce türün sınırlarını kontrol etmek amacıyla <limits.h> içindeki makroları kullanmak veya statik analiz araçlarını kullanmak önerilir. Modern derleyiciler ve araçlar olası taşmaları tespit edebilir.
Kod Örneği:
#include <stdio.h> #include <limits.h> int add_with_check(int a, int b) { if (a > 0 && b > INT_MAX - a) { printf("Taşma olacak! "); return -1; } return a + b; } int main() { int x = INT_MAX, y = 1; printf("Sonuç: %d ", add_with_check(x, y)); unsigned int ux = UINT_MAX; printf("Unsigned taşma: %u ", ux + 1); return 0; }
Ana Özellikler:
<limits.h> kullanınUnsigned tipindeki taşma bir hata mıdır?
Hayır, bu davranış standartla tanımlıdır ve modulo sıfırlama ile eşdeğerdir. Örneğin, (unsigned int)UINT_MAX + 1 == 0 her zaman doğrudur.
Taşma durumunda int sonucunun sadece "INT_MIN" üzerinden geçeceğine güvenebilir miyiz?
Hayır, bu davranış garanti edilmez ve standartlaştırılmamıştır; bu bir belirsiz davranıştır. Çökmeye yol açabilir, yanlış (farklı platformlarda) bir değere verebilir veya derleyici tarafından tahmin edilemez bir şekilde optimize edilebilir.
Int'in her zaman iki tamamlayıcı olduğu varsayımında bulunabilir miyiz?
Modern donanım neredeyse her zaman imzalı int'i temsil etmek için "two's complement" kullanmasına rağmen, C dili bunu standart olarak talep etmez, bu nedenle taşma kodu taşınabilir olmayacaktır.
Sınır kontrolleri olmadan int sayılarının toplanması - büyük verilerde taşma, geçersiz hesaplamalara yol açar.
Artıları:
Eksileri:
Tüm aritmetik işlemlerden önce taşma kontrolü yapılır. Wraparound'un kabul edilebilir olduğu yerlerde unsigned kullanılır.
Artıları:
Eksileri: