In de programmeertaal C kunnen wiskundige bewerkingen met integer types leiden tot overflow, wanneer het resultaat buiten het representatieve bereik van het type valt, bijvoorbeeld int of unsigned int. De specificiteit van het gedrag bij overflow is vastgelegd in de standaarden van de taal.
Overflow bij een signed type leidt tot undefined behavior, dat wil zeggen dat de compiler het recht heeft om verschillende acties uit te voeren: de fout negeren, een uitzondering genereren of een onvoorspelbaar resultaat geven. Voor unsigned types is het gedrag bij overflow volgens de standaard C gedefinieerd: er vindt een wraparound plaats modulo de grootte van het type.
Voor unsigned getallen is het resultaat van overflow gemakkelijk te voorspellen, bijvoorbeeld UINT_MAX + 1 == 0. Voor signed getallen is het aan te raden om voor de bewerkingen de grenzen van het type te controleren met behulp van macro's uit <limits.h> of gebruikmakend van statische analysetools. Moderne compilers en tools kunnen potentiële overflows identificeren.
Codevoorbeeld:
#include <stdio.h> #include <limits.h> int add_with_check(int a, int b) { if (a > 0 && b > INT_MAX - a) { printf("Er zal een overflow optreden! "); return -1; } return a + b; } int main() { int x = INT_MAX, y = 1; printf("Resultaat: %d ", add_with_check(x, y)); unsigned int ux = UINT_MAX; printf("Unsigned overflow: %u ", ux + 1); return 0; }
Belangrijkste kenmerken:
<limits.h> voor het verkrijgen van de groottes van typesIs overflow van een unsigned type een fout?
Nee, dit gedrag is gedefinieerd door de standaard en is gelijk aan een wraparound. Bijvoorbeeld, (unsigned int)UINT_MAX + 1 == 0 is altijd waar.
Kun je vertrouwen op het feit dat bij overflow van int het resultaat gewoon "door INT_MIN heen gaat"?
Nee, dergelijk gedrag is niet gegarandeerd en niet gestandaardiseerd, dit is undefined behavior. Het kan crashen, een onjuist (verschillend op platforms) resultaat geven of op onvoorspelbare wijze door de compiler geoptimaliseerd worden.
Kun je rekenen op het gedrag dat int altijd two's complement is?
Hoewel moderne hardware vrijwel altijd «two's complement» gebruikt voor de representatie van signed int, vereist de programmeertaal C dit standaard niet, waardoor code met overflow niet draagbaar is.
Optelling van int getallen zonder controle op grenzen — overflow bij grote gegevens leidt tot ongeldige berekeningen.
Voordelen:
Nadelen:
Voor alle wiskundige bewerkingen wordt er een controle op overflow uitgevoerd met behulp van macro's en functies. Gebruik unsigned waar wraparound toegestaan is.
Voordelen:
Nadelen: