Dipende molto dal contesto.
In generale qualche modo per evitare la fila di if c'è, ma dipende dai fattori con cui operi.
Se ad esempio le funzioni che utilizzi ritornano 0 in caso di fallimento e 1 in caso di successo, puoi sfruttare la short-circuit evaluation dell'operatore and, se il tuo linguaggio lo supporta, facendo dunque:
codice:
if(A && B && C && D)
{
// ok
}
else
{
// errore
}
Hai la certezza che D verrà eseguita solo se C va a buon fine. C sse B va a buon fine, B sse A va a buon fine.
Oppure puoi utilizzare la gestione delle eccezioni. Supponendo che tutte le funzioni lancino un'eccezione in caso di errore:
codice:
try {
A;
B;
C;
D;
} catch(Expection& e)
{
// ...
}
Se un operazione lancia un'eccezione, sei certo che nessun'altra operazione successiva nel blocco try venga eseguita.
Personalmente utilizzo questa, quando posso.