Skip to content

Alternative alle Eccezioni: Error Codes e Structured Bindings

Esistono ambienti di programmazione (come i sistemi embedded hard real-time o il codice del kernel dei sistemi operativi) dove l’utilizzo delle eccezioni è interdetto perché lo stack unwinding comporta un ritardo che rende l’esecuzione imprevedibile. In altri casi, ti trovi a interfacciarti con codice legacy C che ignora cosa sia un’eccezione.

In questi frangenti, bisogna ripiegare sugli storici Error Codes, combinandoli con feature del C++ moderno per renderne l’uso piacevole.

Prima dell’avvento di strutture complesse e tuple, la gestione degli errori “alla vecchia maniera” implicava ritornare un numero intero (il codice di errore) dalla funzione, e modificare il vero risultato desiderato passando un puntatore come argomento (spesso chiamato out parameter).

// Ritorna 0 se successo, -1 se errore (es. divisione per zero)
int dividi(int a, int b, int* risultato_in_uscita) {
if (b == 0) return -1; // ERRORE!
*risultato_in_uscita = a / b;
return 0; // SUCCESSO
}
int main() {
int risultato = 0;
// Bisogna testare il return prima di toccare 'risultato'
if (dividi(10, 2, &risultato) == 0) {
printf("Risultato: %d\\n", risultato);
} else {
printf("Errore matematico!\\n");
}
}

Questo approccio, seppur ultra-performante e sicuro per i kernel, sporca incredibilmente la firma delle funzioni e la leggibilità.

Il modo nativo del C di segnalare un problema era ritornare parametri da una funzione in modo poco ortodosso, o restituire un booleano per validare il calcolo. Il C++ odierno supporta le Structured Binding Declarations, una sintassi splendida introdotta con il C++17 che permette alle funzioni di ritornare strutture dati complete e al chiamante di “disimballarle” (unpack) immediatamente.

L’uso di auto [variabile1, variabile2] = funzione(); (Structured Bindings) garantisce che tu possa trattare le tue funzioni un po’ come se restituissero multiple tuple, garantendo una leggibilità superlativa quando vuoi riportare un errore anziché lanciare un’eccezione.

(Questa sintassi viene ulteriormente migliorata in standard successivi con classi monadiche come std::optional e std::expected che esploreremo nelle parti avanzate).