Off-by-one error

Versione del 4 nov 2017 alle 12:40 di Tommycuki (discussione | contributi) (Aggiunto capitolo "Iterazioni oltre il termine dell'array")

Un errore off-by-one error (OBOE), detto anche OBOB (off-by-one bug), è un errore logico di programmazione che avviene quando un ciclo iterativo viene ripetuto una volta di troppo o una volta di meno, a causa di un errore nella specifica della condizione di verità: solitamente accade quando il programmatore mette erroneamente il simbolo di minore o uguale al posto del simbolo minore, o il simbolo maggiore o uguale al posto di maggiore, oppure quando commette un errore nell'inizializzazione della variabile testata, settandola a zero anziché a uno: questo causa problemi ad esempio se essa si riferisce all'indice di un array (il quale in molti linguaggi di programmazione comincia da zero); oppure nel caso in cui essa poi sia usata in una divisione (nel qual caso è bene sia settata a valori diversi da zero, per evitare eccezioni del tipo divisione per zero).

Iterazioni oltre il termine dell'Array

Consideriamo un array di oggetti, dei quali processare quelli compresi da un certo valore m ad uno n (estremi inclusi). Quanti elementi si trovano in questo range? Una risposta intuitiva potrebbe essere nm, ma questo è proprio un errore di off-by-one, più precisamente del tipo fencepost; la risposta corretta è infatti (nm) + 1.

Proprio per via di questa contro-intuitività, i range nell'informatica sono spesso rappresentati da intervalli semi-aperti; il range da m ad n inclusivo infatti, è rappresentato dagli elementi che vanno da m (incluso) ad n + 1  (escluso), proprio per evitare errori di fancepost. Per esempio, un ciclo che itera cinque volte (da 0 a 4 incluso) può essere scritto come un intervallo semi-aperto da 0 a 5:

for (i = 0; i < 5; i++)
{
    //Corpo del ciclo
}

Il corpo del ciclo è eseguito prima di tutto quando i è uguale a 0; successivamente i assume i valori 1,2,3, sino a raggiungere il valore finale 4 nel corso delle iterazioni. A questo punto, i assumerà valore 5, e dato che i<5 è falso il loop termina. In ogni caso, se la comparazione usata fosse stata <= (minore o uguale a), il ciclo sarebbe stato ripetuto 6 volte: i assumerebbe infatti i valori 0,1,2,3,4, e 5 (con un'ultima ripetizione all'assunzione del valore 5). Analogamente, se i fosse stato inizializzato ad 1 invece che a 0, si sarebbero verificate soltanto quattro iterazioni, relative ai valori 1,2,3, e 4 assunti da i.

Entrambe queste situazioni causerebbero quindi errori di tipo off-by-one.

Un altro tipo di errore può verificarsi se un ciclo do-while viene utilizzato al posto di uno while (o vice versa), poiché quello di tipo do-while è per costruzione ripetuto per forza almeno una volta.

Errori relativi agli array possono inoltre essere risultato di differenze concettuali tra i vari linguaggi di programmazione. La numerazione che fa riferimento alla prima cella come la cella 0 è molto comune, ma alcuni linguaggi la numerano come la 1. Pascal utilizza gli array con indici definiti dagli utenti, rendendone possibile la modellazione successivamente al problema del dominio.

  Portale Informatica: accedi alle voci di Wikipedia che trattano di informatica