Off-by-one-Error

Programmierfehler
Dies ist eine alte Version dieser Seite, zuletzt bearbeitet am 24. März 2005 um 00:10 Uhr durch Zwobot (Diskussion | Beiträge) (Bot-unterstützte Begriffsklärung: C). Sie kann sich erheblich von der aktuellen Version unterscheiden.

Off-By-One-Fehler, auch Off-By-One-Error (engl. Um-Eins-Daneben-Fehler). Eine bestimmte Art von Fehler, die einem Programmierer beim Schreiben von Quelltext unterlaufen kann. Off-By-One-Fehler werden "gerne gemacht" (d.h. können recht einfach passieren), da sie auf einem logischen Denkfehler oder einer Ungenauigkeit des logischen Denkens basieren.

Einen Off-By-One-Fehler macht ein Programmierer, wenn er im Umgang mit Schleifen, Feldern / Arrays / Vektoren / Listen / indizierbaren Datentypen eine Kontrollstruktur auf solche Weise fehlerhaft gestaltet, dass sie entweder einmal zu oft oder einmal zu wenig durchlaufen wird.

Im Falle eines Off-By-One-Errors wird typischerweise beim Schreiben einer Schleife, die ein Feld be-/verarbeiten soll, die Abbruch- bzw. Fortsetzungsbedingung falsch gewählt, so dass im Rumpf der Schleife eine Anweisung, die index-basiert auf das Feld zugreift, genau einmal zu oft oder einmal zu wenig ausgeführt wird, wodurch entweder versucht wird, auf ein Element des Feldes zuzugreifen, das nicht existiert, oder das letzte Element des Feldes ausgelassen wird. Im erstgenannten Fall ist oft ein Index-Out-Of-Range-Fehler (o.ä.) die auffällige Folge, im letztgenannten Fall wird kein Fehler produziert, d.h. dieser Fehler ist schwer zu finden. Je nach gewählter Sprache und Compiler muss allerdings keiner der beiden Fälle zur Laufzeit auffallen. Es sind stille Fehler, die oft lange unbemerkt bleiben können.

Beispiel aus der Sprache C:

int nettopreise[10];
int i;

for (i = 0; i <= 10; i++)
    nettopreise[i] = nettopreise[i] * 1.16; // MWSt aufschlagen.

In diesem Fall müsste es "i < 10" und nicht "i <= 10" heißen, da in der Deklaration zwar 10 als Feldgröße angegeben wurde, aber aufgrund der Nullbasiertheit von C der maximale Index 9 ist.

Auf den Punkt gebracht resultieren Off-By-One-Fehler aus der "Verwirrung", die dadurch entsteht, das Menschen von 1 bis X zählen, Feldindizes in vielen Programmiersprachen aber von 0 bis X-1 gehen. Dann gibt es auch noch das Größer-Als-Zeichen und das Größer-Gleich-Zeichen, die man verwechseln kann, und schließlich kann man ja die Zählvariable auch noch von 1 bis N laufen lassen, dafür aber stets den Ausdruck "Index-1" anstelle von "Index" verwenden. Darüber hinaus ist die Abbruchbedingung auch öfters mal etwas komplizierter, so dass man als Mensch eben einfach mal daneben liegt, und zwar meistens um genau 1 (oder seltener auch 2).

Beispiel aus der Sprache C:

const int anzahlPreise;
int nettopreise[anzahlPreise];
int i;
int startPos; // Position ist immer eins größer als Index.
int anzahlZuVerarbeitenderPreise;

for (i = startPos-1; startPos + anzahlZuVerarbeitenderPreise > i; i++)
    nettopreise[i] = nettopreise[i] * 1.16; // MWSt aufschlagen.