Mi trovi completamente in disaccordo. Come ti è già stato fatto vedere l'uso delle eccezioni rende il codice molto più leggibile e comprensibile, senza contare che rende molto più comode da usare molte funzioni. Usando un approccio in stile Windows API agli errori devi usare sempre il valore di ritorno per il codice di errore (o riservare alla segnalazione di un errore un valore speciale), e il vero valore restituito andrà memorizzato in un parametro passato per riferimento o per indirizzo, rendendo la funzione molto più scomoda da usare. Non solo: le eccezioni risalgono lo stack fino a trovare un gestore adeguato, così non c'è bisogno che delle funzioni "intermedie" si preoccupino di controllare se si sono verificati errori che comunque non saprebbero come gestire: l'eccezione risale in automatico fino alla prima funzione in grado di gestirla, che spesso è l'unica che sa cosa fare se si verifica un problema.
Inoltre le eccezioni non si ignorano così facilmente come i valori restituiti (o quanto meno, per ignorarle bisogna mettere deliberatamente un blocco catchall), così è più difficile che passino inosservate.
Generalmente il flusso di controllo delle strutture tradizionali è piu' chiaro e piu' efficiente.
Sicuramente non è più chiaro (dai un'occhiata allo spaghetti-code postato da MacApp), e se è più efficiente conta molto poco, visto che un'eccezione è, appunto, una situazione eccezionale, per cui anche se non è efficientissima è difficile che abbia un impatto percepibile sulle prestazioni del programma.
Riprendendo il caso del "Faccio librerie che uso io stesso", avendo il codice sorgente in mano, è possibile rendere ogni gestione di errori interna al luogo in cui possono verificarsi.
Sì, ma usando questo sistema è facile ottenere del codice illeggibile, senza contare che il passaggio della gestione dell'errore alla routine chiamante è sempre un pasticcio (come già detto poco sopra).