| 121 | Dicembre 2007 | 10 cose da NON fare in C++ |
| Errata corrige | ||
|
Per la prima volta dall'inizio di questa rubrica sono costretto a segnalare un mio grave errore, e mi dispiace che avvenga proprio in una puntata dedicata agli errori in C++. Purtroppo è accaduto uno di quegli sbagli dovuti alla sciagurata sovrapposizione di versioni successive del pezzo. Uno di quelli che noti solo quando rileggi quello che hai scritto a mente fredda, e inorridisci, e segnali subito la cosa al tuo editore, e tiri un sospiro di sollievo, e poi ti arriva la rivista, e ti accorgi che l'errore è sempre lì. (Non vi è mai successo? A me sì. Oggi.) Il grave errore sta nell'esempio relativo al primo punto: per i numeri unsigned lo standard garantisce il "wrap around", quindi l'obiezione sul comportamento indefinito in caso di underflow crolla (rimane quella sul range dei tipi char, però). Per farmi perdonare, ecco come sarebbe dovuto andare in stampa il pezzo secondo l'errata corrige 1) "Compila, quindi è giusto!" Questo non è un errore, di per sé. Ciò nonostante si conquista senza alcun dubbio la prima posizione in quanto capostipite di una numerosa famiglia di errori. Si tratta dell’atteggiamento tipico del neofita, che, un po’ per inesperienza e un po’ per pigrizia pensa che il fatto che un compilatore accetti una scrittura implichi necessariamente che questa sia corretta. Non è cosi. L'unica fonte attendibile che stabilisce cosa sia da considerarsi corretto nel C++ è lo standard. Non sono invece attendibili: il tutorial scritto da un quattordicenne su Internet, le garanzie di “miocuggino che è espertissimo”, e ancor meno il comportamento dei compilatori [e neanche i miei articoli, evidentemente, almeno finché non pubblico gli errata corrige :ashamed:]. I compilatori, infatti, applicano spesso qualche deviazione o estensione rispetto al C++ standard, e devono necessariamente adottare qualche arbitrio nell’interpretazione dei famosi comportamenti dipendenti dall’implementazione, non specificati, o indefiniti. Facciamo un test pratico:
#include <iostream> int main() { Quale sarà l’output dell’applicazione? Provate a rispondere da voi, prima di continuare la lettura. Fatto? L’unica risposta corretta è: “boh?”. Questo, infatti, è un tipico caso di comportamento indefinito. Non si sa cosa succederà in esecuzione, perché lo standard non stabilisce:
Quindi se avete risposto che stampa “-128”, avete "sbagliato". E non fa niente: sbagliamo tutti, specialmente negli esempi infidi in un linguaggio insidioso come C++. Il punto è un altro: se lo provate sul vostro compilatore di fiducia e questo stampa “.-128”, o “128” o arresta l’applicazione, o qualsiasi altra cosa, non significa che questo sia il comportamento “giusto”. (In questo caso, infatti, non c’è un comportamento "giusto"). |
||
Copyright Roberto Allegra, 2006. All rights reserved.
I codici sorgenti sono presentati in via provvisoria per gentile concessione della Edizioni Master, che ne detiene ogni diritto.