Gestione delle eccezioni

costrutto dei linguaggi di programmazione

In informatica la gestione delle eccezioni è un costrutto dei linguaggi di programmazione o un meccanismo dell'hardware del computer progettato per gestire errori a runtime o altri problemi (eccezioni) che avvengono durante l'esecuzione di un programma su un computer.

In generale, lo stato attuale verrà salvato in una posizione predefinita e l'esecuzione passerà a un gestore predefinito handler. A seconda della situazione, il gestore può poi riprendere l'esecuzione alla posizione originale, usando l'informazione salvata per ripristinare lo stato originale. Un esempio di eccezione da cui solitamente si riprende l'esecuzione è il page fault, mentre una che solitamente non può essere risolta trasparentemente è la divisione per zero.

Dal punto di vista dell'elaborazione, gli interrupt hardware sono simili a eccezioni recuperabili, eccetto che solitamente non sono correlate con il flusso attuale del programma.

Descrizione

modifica

Scopi delle eccezioni

modifica

La gestione delle eccezioni è rivolta a facilitare l'uso di meccanismi ragionevoli per gestire situazioni erronee o eccezionali che sorgono nei programmi. La gestione delle eccezioni può essere usata per passare informazioni sulle situazioni d'errore che avvengono all'interno di codice di libreria ai suoi utenti, e rispondere selettivamente a quegli errori.

Un possibile ruolo della gestione delle eccezioni è di permettere al programma di continuare la sua normale operatività e prevenire errori interni (crash), che comportano la visualizzazione di messaggi d'errore di difficile comprensione per l'utente. In molti casi, è sufficiente arrestare il programma e produrre un resoconto dell'errore; la differenza rispetto a sistemi che non fanno uso di eccezioni per segnalare esecuzioni anomale del programma sta nel fatto che con un'appropriata gestione delle eccezioni la condizione erronea può essere localizzata con precisione, semplificando il debugging.

La gestione delle eccezioni rende obsoleta la tecnica di gestione dei segnali presente in alcuni linguaggi.

Strutture di controllo

modifica

Le eccezioni sono definite da linguaggi come C++, D, Java, C# e Python. La struttura di controllo utilizzata è il try-catch: alcuni linguaggi supportano ulteriori clausole, come finally o else.

  Lo stesso argomento in dettaglio: Gestione delle eccezioni in Java.

Si consideri questo semplice blocco di codice Java: si dichiara un array di interi di dimensione 5, e si prova ad accedere alla cella di memoria in una determinata posizione. Java genera un'eccezione se si prova ad accedere a tale porzione di memoria, se l'indice è maggiore o uguale della dimensione dell'array: questa eccezione può essere catturata in un blocco catch.

int posizione = ...;

try{
    // dichiaro un array di interi di lunghezza 5
    int array[]=new int[5];
    // provo ad accedere alla posizione dell'array
    // ma potrebbe essere maggiore della dimensione dell'array
    array[posizione]=0; 
}
catch(ArrayIndexOutOfBoundsException e){
    System.out.println("Errore nell'accesso all'array");
}

In Python è possibile gestire un'eccezione in un blocco try-except. In questo esempio, il programma accetta una stringa in input e prova a convertirla in intero e termina dopo aver calcolato e stampato a schermo il doppio del numero inserito. Se la stringa inserita non può essere convertita, però, viene generata un'eccezione di tipo ValueError. Il programma cattura questa eccezione ed esegue il codice all'interno del blocco except, stampando un messaggio di errore. Nel blocco finally, infine, si può scrivere del codice che viene eseguito al termine del blocco try-except.

try:
    intero = int(input("Inserisci un intero: "))
    # l'esecuzione continua normalmente se non viene generata un'eccezione
    doppio = intero * 2
    print(f"Il doppio di {intero} è {doppio}.")
except ValueError:
    print("Errore, non hai inserito un intero.")
finally:
    print("Il programma è terminato.")

In questo semplice esempio C++, il programma legge in input un intero, e stampa a schermo il risultato di una divisione nella quale il numero letto in input funge da denominatore. Se tale numero è 0, il programma stampa un messaggio di errore.

#include <iostream>

int main(){
    int numeratore = 10;
    int denominatore;
    // leggo in input il valore del denominatore
    std::cin >> denominatore;
    
    try{
		if (denominatore == 0){
		    // genero un'eccezione
			throw 0;
		}
		// denominatore diverso da 0, stampo il risultato della divisione
        std::cout << a/b << endl;
    } 
    catch (int n) {
        std::cout << "Denominatore zero." << std::endl;
    }

    return 0;
}

Bibliografia

modifica
  • Gian Carlo Macchi, Le condizioni eccezionali e la loro gestione, in Newsletter AICA "Affidabilità nei Sistemi di Elaborazione", n. 2, Scuola Superiore Guglielmo Reiss Romoli, maggio 1987. URL consultato il 25 novembre 2018.

Voci correlate

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