In der Programmiersprache C können arithmetische Operationen mit Ganzzahltypen zu einem Überlauf (overflow) führen, wenn das Ergebnis den darstellbaren Bereich des Typs überschreitet, z.B. int oder unsigned int. Das Verhalten bei einem Überlauf ist durch die Standards der Sprache festgelegt.
Ein Überlauf mit vorzeichenbehaftetem Typ (signed overflow) führt zu undefined behavior, das heißt, der Compiler hat das Recht, beliebige Aktionen auszuführen: den Fehler zu ignorieren, eine Ausnahme zu generieren oder ein unvorhersehbares Ergebnis zu hinterlassen. Für vorzeichenlose Typen (unsigned) ist das Verhalten laut C-Standard definiert: Es erfolgt ein Rücklauf modulo der Größe des Typs (wraparound).
Für vorzeichenlose Zahlen ist das Ergebnis eines Überlaufs leicht vorhersehbar, zum Beispiel UINT_MAX + 1 == 0. Für vorzeichenbehaftete Zahlen wird empfohlen, die Grenzen des Typs vor den Operationen mit Hilfe von Makros aus <limits.h> zu überprüfen oder statische Analysewerkzeuge zu verwenden. Moderne Compiler und Werkzeuge können potenzielle Überläufe erkennen.
Beispielcode:
#include <stdio.h> #include <limits.h> int add_with_check(int a, int b) { if (a > 0 && b > INT_MAX - a) { printf("Es wird eine Überlauf auftreten! "); return -1; } return a + b; } int main() { int x = INT_MAX, y = 1; printf("Ergebnis: %d ", add_with_check(x, y)); unsigned int ux = UINT_MAX; printf("Unsigned Überlauf: %u ", ux + 1); return 0; }
Wichtige Merkmale:
<limits.h> zur Bestimmung der TypgrößenIst der Überlauf eines unsigned Typs ein Fehler?
Nein, dieses Verhalten ist im Standard definiert und entspricht einem Rücklauf modulo. Zum Beispiel, (unsigned int)UINT_MAX + 1 == 0 ist immer wahr.
Kann man sich darauf verlassen, dass der int bei einem Überlauf einfach "überschreitet" INT_MIN?
Nein, dieses Verhalten ist nicht garantiert und nicht standardisiert, es handelt sich um undefined behavior. Es kann abstürzen, einen inkorrekten (plattformabhängigen) Wert zurückgeben oder vom Compiler auf unvorhersehbare Weise optimiert werden.
Kann man darauf vertrauen, dass int immer im Zweierkomplement dargestellt wird?
Obwohl moderne Hardware fast immer „two's complement“ zur Darstellung von signed int verwendet, schreibt der C-Standard dies nicht vor, daher ist Code mit Überlauf nicht portierbar.
Addition von int-Zahlen ohne Überprüfung der Grenzen — Überlauf mit großen Daten führt zu ungültigen Berechnungen.
Vorteile:
Nachteile:
Vor allen arithmetischen Operationen wird eine Überlaufprüfung mittels Makros und Funktionen durchgeführt. Verwendung von unsigned, wo wraparound zulässig ist.
Vorteile:
Nachteile: