Questa è una storia infinita che riflette i limiti (un mito) di "interoperabilità e portabilità su tutto".
Ciò che il programma dovrebbe restituire per indicare "successo" dovrebbe essere definito da chi riceve il valore (il sistema operativo o il processo che ha invocato il programma) non da una specifica del linguaggio.
Ma ai programmatori piace scrivere codice in "modo portabile" e quindi inventano il proprio modello per il concetto di "sistema operativo" definendo valori simbolici da restituire.
Ora, in uno scenario molti-a-molti (dove molti linguaggi servono a scrivere programmi su molti sistemi) la corrispondenza tra la convenzione linguistica per il "successo" e quella del sistema operativo (che nessuno può garantire che sia sempre la stessa) dovrebbe essere gestito dall'implementazione specifica di una libreria per una specifica piattaforma di destinazione.
Ma - sfortunatamente - questi concetti non erano così chiari al momento in cui il linguaggio C è stato distribuito (principalmente per scrivere il kernel UNIX), e gigagrammi di libri dove scritti dicendo "return 0 significa successo", dal momento che questo era vero sul sistema operativo a quella volta con un compilatore C.
Da quel momento in poi, non è mai stata fatta una chiara standardizzazione sul modo in cui tale corrispondenza dovrebbe essere gestita. C e C ++ hanno la propria definizione di "valori di ritorno" ma nessuno garantisce una corretta traduzione del sistema operativo (o meglio: nessuna documentazione del compilatore dice nulla al riguardo). 0 significa successo se vero per UNIX - LINUX e -per ragioni indipendenti- anche per Windows, e questo copre il 90% dei "computer consumer" esistenti, che - nella maggior parte dei casi - ignorano il valore restituito (quindi possiamo discutere per decenni, ma nessuno se ne accorgerà mai!)
All'interno di questo scenario, prima di prendere una decisione, poni queste domande: - Sono interessato a comunicare qualcosa al mio chiamante sulla mia esistenza? (Se restituisco sempre 0 ... non c'è alcun indizio dietro a tutto) - Il mio chiamante ha convenzioni su questa comunicazione? (Nota che un singolo valore non è una convenzione: ciò non consente alcuna rappresentazione delle informazioni)
Se entrambe le risposte sono no, probabilmente la buona soluzione è non scrivere affatto l'istruzione return principale. (E lascia che sia il compilatore a decidere, rispetto alla destinazione su cui sta lavorando).
Se non sono presenti convenzioni 0 = il successo soddisfa la maggior parte delle situazioni (e l'uso di simboli può essere problematico, se introducono una convenzione).
Se esistono convenzioni, assicurarsi di utilizzare costanti simboliche coerenti con esse (e garantire la coerenza delle convenzioni, non la coerenza dei valori, tra le piattaforme).