Cosa dovrebbe restituire main () in C e C ++?

Qual è il modo corretto (più efficiente) per definire la funzione main() in C e C ++ – int main() o void main() – e perché? Se int main() return 1 o return 0 ?


Esistono numerosi duplicati di questa domanda, tra cui:

  • Quali sono le firme valide per la funzione main() di C?
  • Il tipo di ritorno della funzione main()
  • Differenza tra void main() e int main() ?
  • firma di main() in C ++
  • Qual è la dichiarazione corretta di main() ? – Per C ++, con una risposta davvero buona.
  • Stili delle funzioni main() in C
  • Restituisce il tipo di metodo main() in C
  • int main() vs void main() in C

Relazionato:

  • C ++ – int main(int argc, char **argv)
  • C ++ – int main(int argc, char *argv[])
  • char *envp[] un terzo argomento per main() portable?
  • La funzione int main() restituire un valore in tutti i compilatori?
  • Perché il tipo della funzione main() in C e C ++ è stato definito dall’utente?
  • Perché int main(){} compilare?
  • Definizioni legali di main() in C ++ 14?

Il valore di ritorno per main dovrebbe indicare come il programma è uscito. L’uscita normale è generalmente rappresentata da un valore di ritorno 0 da main . La terminazione anomala viene solitamente segnalata da un ritorno diverso da zero, ma non esiste uno standard per l’interpretazione dei codici diversi da zero. Inoltre, come notato da altri, void main() è esplicitamente vietato dallo standard C ++ e non dovrebbe essere usato. Le firme main C ++ valide sono:

 int main() 

e

 int main(int argc, char* argv[]) 

che è equivalente a

 int main(int argc, char** argv) 

Vale anche la pena notare che in C ++, int main() può essere lasciato senza un valore di ritorno, a quel punto il suo valore predefinito è il valore 0. Questo vale anche per un programma C99. Se il reso 0 dovrebbe essere omesso o no è aperto al dibattito. L’intervallo di firme principali del programma C valido è molto maggiore.

Inoltre, l’efficienza non è un problema con la funzione main . Può essere inserito e lasciato una sola volta (contrassegnando l’inizio e la fine del programma) in base allo standard C ++. Per C, il caso è diverso e il reinserimento in main() è consentito, ma probabilmente dovrebbe essere evitato.

La risposta accettata sembra essere indirizzata al C ++, quindi ho pensato di aggiungere una risposta relativa a C, e questo differisce in alcuni modi.

ISO / IEC 9899: 1989 (C90):

main() dovrebbe essere dichiarato come:

 int main(void) int main(int argc, char **argv) 

O equivalente. Ad esempio, int main(int argc, char *argv[]) è equivalente al secondo. Inoltre, il tipo di ritorno int può essere omesso poiché è un valore predefinito.

Se un’implementazione lo consente, main() può essere dichiarato in altri modi, ma ciò rende l’implementazione del programma definita e non più strettamente conforms.

Lo standard definisce 3 valori per la restituzione che sono strettamente conformi (ovvero, non si basano sul comportamento definito dall’implementazione): 0 e EXIT_SUCCESS per una terminazione corretta e EXIT_FAILURE per una terminazione non riuscita. Qualsiasi altro valore è non standard e definito dall’implementazione. main() deve avere un’istruzione di return esplicita alla fine per evitare comportamenti non definiti.

Infine, non c’è nulla di sbagliato dal punto di vista degli standard con la chiamata a main() da un programma.

ISO / IEC 9899: 1999 (C99):

Per C99, tutto è uguale a sopra tranne:

  • Il tipo di ritorno int non può essere omesso.
  • Puoi omettere la dichiarazione di ritorno da main() . Se lo fai, e main() finito, c’è un return 0 implicito return 0 .

Standard C – Ambiente ospitato

Per un ambiente ospitato (quello normale), lo standard C11 (ISO / IEC 9899: 2011) dice:

5.1.2.2.1 Avvio del programma

La funzione chiamata all’avvio del programma è denominata main . L’implementazione non dichiara alcun prototipo per questa funzione. Deve essere definito con un tipo restituito di int e senza parametri:

 int main(void) { /* ... */ } 

o con due parametri (indicati qui come argc e argv , sebbene possano essere usati tutti i nomi, poiché sono locali alla funzione in cui sono dichiarati):

 int main(int argc, char *argv[]) { /* ... */ } 

o equivalente; 10) o in qualche altro modo definito dall’implementazione.

Se vengono dichiarati, i parametri della funzione principale devono rispettare i seguenti vincoli:

  • Il valore di argc deve essere non negativo.
  • argv[argc] deve essere un puntatore nullo.
  • Se il valore di argc è maggiore di zero, i membri dell’array argv[0] tramite argv[argc-1] inclusi devono contenere i puntatori alle stringhe, che ricevono valori definiti dall’implementazione dall’ambiente host prima dell’avvio del programma. L’intento è quello di fornire le informazioni sul programma determinate prima dell’avvio del programma da altrove nell’ambiente ospitato. Se l’ambiente host non è in grado di fornire stringhe con lettere maiuscole e minuscole, l’implementazione deve garantire che le stringhe vengano ricevute in lettere minuscole.
  • Se il valore di argc è maggiore di zero, la stringa puntata da argv[0] rappresenta il nome del programma; argv[0][0] deve essere il carattere null se il nome del programma non è disponibile dall’ambiente host. Se il valore di argc è maggiore di uno, le stringhe puntate da argv[1] tramite argv[argc-1] rappresentano i parametri del programma.
  • I parametri argc e argv e le stringhe puntate dall’array argv devono essere modificabili dal programma e conservare i loro ultimi valori memorizzati tra l’avvio del programma e la fine del programma.

10) Quindi, int può essere sostituito da un nome typedef definito come int , oppure il tipo di argv può essere scritto come char **argv , e così via.

Fine del programma in C99 o C11

Il valore restituito da main() viene trasmesso all”ambiente ‘in un modo definito dall’implementazione.

5.1.2.2.3 Fine del programma

1 Se il tipo restituito della funzione main è un tipo compatibile con int , un ritorno dalla chiamata iniziale alla funzione main equivale a chiamare la funzione di exit con il valore restituito dalla funzione main come argomento; 11) raggiungendo il } che termina la funzione main restituisce un valore di 0. Se il tipo restituito non è compatibile con int , lo stato di terminazione restituito all’ambiente host non è specificato.

11) Conformsmente al punto 6.2.4, la durata di oggetti con durata di conservazione automatica dichiarata in main sarà terminata nel primo caso, anche se non avrebbero avuto nel secondo caso.

Si noti che 0 è obbligatorio come “successo”. Puoi usare EXIT_FAILURE e EXIT_SUCCESS da se preferisci, ma 0 è ben stabilito, e lo è anche 1. Vedi anche Codici di uscita maggiori di 255 – ansible? .

In C89 (e quindi in Microsoft C), non c’è alcuna dichiarazione su cosa succede se la funzione main() restituisce ma non specifica un valore di ritorno; porta quindi a un comportamento indefinito.

7.22.4.4 La funzione di exit

¶5 Infine, il controllo viene restituito all’ambiente host. Se il valore dello status è zero o EXIT_SUCCESS , viene EXIT_SUCCESS un modulo definito dall’implementazione dello stato. Se il valore dello status è EXIT_FAILURE , viene EXIT_FAILURE un modulo definito dall’implementazione della terminazione non riuscita dello stato. Altrimenti lo stato restituito è definito dall’implementazione.

Standard C ++ – Ambiente ospitato

Lo standard C ++ 11 (ISO / IEC 14882: 2011) dice:

3.6.1 Funzione principale [basic.start.main]

¶1 Un programma deve contenere una funzione globale chiamata main, che è l’inizio designato del programma. […]

¶2 Un’implementazione non deve predefinire la funzione principale. Questa funzione non deve essere sovraccaricata. Deve avere un tipo di ritorno di tipo int, ma in caso contrario il suo tipo è definito dall’implementazione. Tutte le implementazioni devono consentire entrambe le seguenti definizioni di principali:

 int main() { /* ... */ } 

e

 int main(int argc, char* argv[]) { /* ... */ } 

Nell’ultima forma argc deve essere il numero di argomenti passati al programma dall’ambiente in cui viene eseguito il programma. Se argc è argc zero questi argomenti devono essere forniti in argv[0] tramite argv[argc-1] come puntatori ai caratteri iniziali delle stringhe multibyte con terminazione nulla (NTMBS) (17.5.2.1.4.2) e argv[0] devono essere il puntatore al carattere iniziale di un NTMBS che rappresenta il nome utilizzato per richiamare il programma o "" . Il valore di argc deve essere non negativo. Il valore di argv[argc] deve essere 0. [Nota: si consiglia di aggiungere ulteriori parametri (facoltativi) dopo argv . -End note]

¶3 La funzione main non deve essere utilizzata all’interno di un programma. Il collegamento (3.5) di main è definito dall’implementazione. […]

¶5 Un’istruzione return in main ha l’effetto di lasciare la funzione main (distruggere qualsiasi object con durata di archiviazione automatica) e chiamare std::exit con il valore di ritorno come argomento. Se il controllo raggiunge la fine della main senza incontrare un’istruzione return, l’effetto è quello dell’esecuzione

 return 0; 

Lo standard C ++ dice esplicitamente “It [la funzione principale] deve avere un tipo restituito di tipo int , ma altrimenti il ​​suo tipo è definito dall’implementazione” e richiede le stesse due firme dello standard C da supportare come opzioni. Quindi un ‘void main ()’ non è direttamente consentito dallo standard C ++, sebbene non ci sia nulla che possa fare per fermare un’implementazione non standard che permetta alternative. Nota che C ++ proibisce all’utente di chiamare main (ma lo standard C no).

C’è un paragrafo di §18.5 Avvio e terminazione nello standard C ++ 11 che è identico al paragrafo di §7.22.4.4 La funzione di exit nello standard C11 (citata sopra), a parte una nota a piè di pagina (che semplicemente documenta che EXIT_SUCCESS e EXIT_FAILURE sono definiti in ).

Standard C – Estensione comune

Classicamente, i sistemi Unix supportano una terza variante:

 int main(int argc, char **argv, char **envp) { ... } 

Il terzo argomento è un elenco terminato da null di puntatori a stringhe, ognuna delle quali è una variabile di ambiente che ha un nome, un segno di uguale e un valore (eventualmente vuoto). Se non lo usi, puoi comunque accedere all’ambiente tramite ‘ extern char **environ; ‘. Per molto tempo, questo non aveva un’intestazione che lo dichiarasse, ma lo standard POSIX 2008 ora richiede che sia dichiarato in .

Questo è riconosciuto dallo standard C come un’estensione comune, documentata nell’allegato J:

J.5.1 Argomentazioni sull’ambiente

¶1 In un ambiente ospitato, la funzione principale riceve un terzo argomento, char *envp[] , che punta a una matrice di puntatori a terminazione null in char , ognuno dei quali punta a una stringa che fornisce informazioni sull’ambiente per questa esecuzione del programma (5.1.2.2.1).

Microsoft C

Il compilatore Microsoft VS 2010 è interessante. Il sito web dice:

La syntax della dichiarazione per main è

  int main(); 

o, facoltativamente,

 int main(int argc, char *argv[], char *envp[]); 

In alternativa, le funzioni main e wmain possono essere dichiarate come return void (nessun valore restituito). Se dichiari main o wmain come wmain void, non puoi restituire un codice di uscita al processo genitore o al sistema operativo usando un’istruzione return. Per restituire un codice di uscita quando main o wmain sono dichiarati come void , è necessario utilizzare la funzione exit .

Non è chiaro per me cosa succede (quale codice di uscita viene restituito al genitore o al sistema operativo) quando un programma con void main() si chiude e anche il sito Web di MS non funziona.

È interessante notare che MS non prescrive la versione a due argomenti di main() richiesta dagli standard C e C ++. Si prescrive solo una forma a tre argomenti in cui il terzo argomento è char **envp , un puntatore a un elenco di variabili di ambiente.

La pagina Microsoft elenca anche altre alternative – wmain() che prende stringhe di caratteri estese, e altre ancora.

La versione Microsoft Visual Studio 2005 di questa pagina non elenca void main() come alternativa. Le versioni da Microsoft Visual Studio 2008 in poi lo fanno.

Standard C – Ambiente indipendente

Come notato in precedenza, i requisiti sopra riportati si applicano agli ambienti ospitati. Se si sta lavorando con un ambiente indipendente (che è l’alternativa a un ambiente ospitato), lo standard ha molto meno da dire. Per un ambiente indipendente, la funzione chiamata all’avvio del programma non deve essere chiamata main e non ci sono vincoli sul suo tipo di ritorno. Lo standard dice:

5.1.2 Ambienti di esecuzione

Sono definiti due ambienti di esecuzione: indipendenti e ospitati. In entrambi i casi, l’avvio del programma si verifica quando viene richiamata una determinata funzione C dall’ambiente di esecuzione. Tutti gli oggetti con durata di memorizzazione statica devono essere inizializzati (impostati sui loro valori iniziali) prima dell’avvio del programma. Il modo e i tempi di tale inizializzazione sono altrimenti non specificati. La fine del programma restituisce il controllo all’ambiente di esecuzione.

5.1.2.1 Ambiente indipendente

In un ambiente indipendente (in cui l’esecuzione del programma C può aver luogo senza alcun vantaggio di un sistema operativo), il nome e il tipo della funzione richiamata all’avvio del programma sono definiti dall’implementazione. Qualsiasi struttura di libreria disponibile per un programma indipendente, oltre al set minimo richiesto dalla clausola 4, è definita dall’implementazione.

L’effetto della terminazione del programma in un ambiente indipendente è definito dall’implementazione.

Il riferimento incrociato alla clausola 4 di conformità si riferisce a questo:

¶5 Un programma strettamente conforms deve usare solo quelle caratteristiche della lingua e della biblioteca specificate in questo Standard Internazionale. 3) Non deve produrre output dipendenti da alcun comportamento non specificato, indefinito o definito dall’implementazione e non deve superare alcun limite minimo di implementazione.

¶6 Le due forms di implementazione conforms sono ospitate e indipendenti . Un’implementazione ospitata conforms accetta qualsiasi programma strettamente conforms. Un’implementazione indipendente conforms deve accettare qualsiasi programma strettamente conforms in cui l’uso delle funzionalità specificate nella clausola della libreria (clausola 7) sia limitato al contenuto delle intestazioni standard , , , , , , , e . Un’implementazione conforms può avere estensioni (incluse funzioni di libreria aggiuntive), a condizione che non alterino il comportamento di alcun programma strettamente conforms. 4)

¶7 Un programma conforms è accettabile per un’implementazione conforms. 5)

3) Un programma strettamente conforms può utilizzare le caratteristiche condizionali (vedere 6.10.8.3) a condizione che l’uso sia protetto da una direttiva di preprocessing di inclusione condizionale appropriata che utilizza la macro correlata. Per esempio:

 #ifdef __STDC_IEC_559__ /* FE_UPWARD defined */ /* ... */ fesetround(FE_UPWARD); /* ... */ #endif 

4) Questo implica che un’attuazione conforms non riserva identificatori diversi da quelli esplicitamente riservati in questo Standard Internazionale.

5) I programmi strettamente conformi sono pensati per essere massimamente trasportabili tra le implementazioni conformi. I programmi conformi possono dipendere da caratteristiche non portabili di un’implementazione conforms.

È evidente che l’unica intestazione richiesta da un ambiente indipendente che definisce effettivamente qualsiasi funzione è (e anche quelli potrebbero essere – e spesso lo sono – solo macro).

Standard C ++ – Ambiente indipendente

Proprio come lo standard C riconosce sia l’ambiente ospitato che quello indipendente, lo stesso vale per lo standard C ++. (Citazioni da ISO / IEC 14882: 2011.)

1.4 Conformità all’implementazione [intro.compliance]

¶7 Sono definiti due tipi di implementazioni: un’implementazione ospitata e un’implementazione indipendente . Per un’implementazione ospitata, questo standard internazionale definisce l’insieme di librerie disponibili. Un’implementazione indipendente è quella in cui l’esecuzione può avvenire senza il beneficio di un sistema operativo e ha un insieme definito di librerie implementate che include alcune librerie di supporto linguistico (17.6.1.3).

¶8 Un’implementazione conforms può avere estensioni (incluse funzioni di libreria aggiuntive), a condizione che non alterino il comportamento di alcun programma ben formato. Le implementazioni sono necessarie per diagnosticare programmi che utilizzano tali estensioni che sono mal formate secondo questo Standard Internazionale. Fatto ciò, tuttavia, possono compilare ed eseguire tali programmi.

¶9 Ogni implementazione deve includere la documentazione che identifica tutti i costrutti supportati condizionalmente che non supporta e definisce tutte le caratteristiche specifiche della locale. 3

3) Questa documentazione definisce anche il comportamento definito dall’implementazione; vedi 1.9.

17.6.1.3 Implementazioni indipendenti [conformità]

Sono definiti due tipi di implementazioni: hosted e freestanding (1.4). Per un’implementazione ospitata, questo standard internazionale descrive l’insieme di intestazioni disponibili.

Un’implementazione indipendente ha un insieme di intestazioni definito dall’implementazione. Questo set deve includere almeno le intestazioni mostrate nella Tabella 16.

La versione fornita dell’intestazione dichiarerà almeno le funzioni abort , atexit , at_quick_exit , exit e quick_exit (18.5). Le altre intestazioni elencate in questa tabella devono soddisfare gli stessi requisiti di un’implementazione ospitata.

Tabella 16 – Intestazioni C ++ per implementazioni indipendenti

 Subclause Header(s)  18.2 Types  18.3 Implementation properties    18.4 Integer types  18.5 Start and termination  18.6 Dynamic memory management  18.7 Type identification  18.8 Exception handling  18.9 Initializer lists  18.10 Other runtime support    20.9 Type traits  29 Atomics  

Che ne dici di usare int main() in C?

Lo standard §5.1.2.2.1 dello standard C11 mostra la notazione preferita – int main(void) – ma ci sono anche due esempi nello standard che mostrano int main() : §6.5.3.4 ¶8 e §6.7.6.3 ¶20 . Ora, è importante notare che gli esempi non sono “normativi”; sono solo illustrativi. Se ci sono errori negli esempi, essi non influenzano direttamente il testo principale dello standard. Detto questo, sono fortemente indicativi del comportamento previsto, quindi se lo standard include int main() in un esempio, suggerisce che int main() non è vietato, anche se non è la notazione preferita.

6.5.3.4 Gli operatori sizeof e _Alignof

¶8 ESEMPIO 3 In questo esempio, la dimensione di una matrice di lunghezza variabile viene calcasting e restituita da una funzione:

 #include  size_t fsize3(int n) { char b[n+3]; // variable length array return sizeof b; // execution time sizeof } int main() { size_t size; size = fsize3(10); // fsize3 returns 13 return 0; } 

Credo che main() debba restituire EXIT_SUCCESS o EXIT_FAILURE . Sono definiti in stdlib.h

Restituisce 0 in caso di successo e non zero per errore. Questo è lo standard utilizzato da script UNIX e DOS per scoprire cosa è successo con il tuo programma.

Si noti che gli standard C e C ++ definiscono due tipi di implementazioni: indipendente e ospitato.

  • C90 ambiente ospitato

    Moduli consentiti 1 :

     int main (void) int main (int argc, char *argv[]) main (void) main (int argc, char *argv[]) /*... etc, similar forms with implicit int */ 

    Commenti:

    I primi due sono esplicitamente dichiarati come forms consentite, gli altri sono implicitamente consentiti perché C90 ha permesso “implicito int” per i parametri di tipo e funzione di ritorno. Non è consentita alcuna altra forma

  • Ambiente indipendente C90

    Qualsiasi forma o nome di principale è permesso 2 .

  • C99 ambiente ospitato

    Moduli consentiti 3 :

     int main (void) int main (int argc, char *argv[]) /* or in some other implementation-defined manner. */ 

    Commenti:

    C99 rimosso “implicit int” così main() non è più valido.

    È stata introdotta una frase strana e ambigua “o in qualche altro modo definito dall’implementazione”. Questo può essere interpretato come “i parametri di int main() possono variare” o come “main può avere qualsiasi forma definita dall’implementazione”.

    Alcuni compilatori hanno scelto di interpretare lo standard in quest’ultimo modo. Probabilmente, non si può facilmente affermare che non sono strettamente conformi citando lo standard in sé, poiché è ambiguo.

    Tuttavia, per consentire forms completamente selvagge di main() era probabilmente (?) Non l’intenzione di questa nuova frase. La logica C99 (non normativa) implica che la frase si riferisca a parametri aggiuntivi a int main 4 .

    Tuttavia, la sezione per la terminazione del programma di ambiente ospitato continua a discutere sul caso in cui main non restituisce int 5 . Sebbene quella sezione non sia normativa per come dovrebbe essere dichiarata la principale, ciò implica sicuramente che la principale potrebbe essere dichiarata in modo completamente definito dall’implementazione anche su sistemi ospitati.

  • Ambiente indipendente C99

    Qualsiasi forma o nome di principale è permesso 6 .

  • C11 ambiente ospitato

    Forme consentite 7 :

     int main (void) int main (int argc, char *argv[]) /* or in some other implementation-defined manner. */ 
  • Ambiente indipendente C11

    Qualsiasi forma o nome di principale è consentito 8 .


Si noti che int main() non è mai stato elencato come modulo valido per qualsiasi implementazione ospitata di C in una delle versioni precedenti. In C, a differenza di C ++, () e (void) hanno significati diversi. Il primo è una caratteristica obsoleta che può essere rimossa dalla lingua. Vedi le indicazioni sul linguaggio futuro C11:

6.11.6 Dichiaratori di funzioni

L’uso di dichiaratori di funzioni con parentesi vuote (non dichiaratori del tipo di parametro in formato prototipo) è una caratteristica obsoleta.


  • C ++ 03 ambiente ospitato

    Moduli consentiti 9 :

     int main () int main (int argc, char *argv[]) 

    Commenti:

    Nota la parentesi vuota nel primo modulo. C ++ e C sono diversi in questo caso, perché in C ++ ciò significa che la funzione non ha parametri. Ma in C significa che può prendere qualsiasi parametro.

  • Ambiente indipendente C ++ 03

    Il nome della funzione chiamata all’avvio è definito dall’implementazione. Se è denominato main() , deve seguire i moduli indicati 10 :

     // implementation-defined name, or int main () int main (int argc, char *argv[]) 
  • C ++ 11 ambiente ospitato

    Moduli consentiti 11 :

     int main () int main (int argc, char *argv[]) 

    Commenti:

    Il testo dello standard è stato cambiato ma ha lo stesso significato.

  • Ambiente indipendente C ++ 11

    Il nome della funzione chiamata all’avvio è definito dall’implementazione. Se è denominato main() , deve seguire i moduli indicati 12 :

     // implementation-defined name, or int main () int main (int argc, char *argv[]) 

Riferimenti

  1. ANSI X3.159-1989 2.1.2.2 Ambiente ospitato. “Avvio del programma”

    La funzione chiamata all’avvio del programma è denominata main. L’implementazione non dichiara alcun prototipo per questa funzione. Deve essere definito con un tipo restituito di int e senza parametri:

     int main(void) { /* ... */ } 

    o con due parametri (indicati qui come argc e argv, sebbene possano essere usati tutti i nomi, poiché sono locali alla funzione in cui sono dichiarati):

     int main(int argc, char *argv[]) { /* ... */ } 
  2. ANSI X3.159-1989 2.1.2.1 Ambiente indipendente:

    In un ambiente indipendente (in cui l’esecuzione del programma C può aver luogo senza alcun vantaggio di un sistema operativo), il nome e il tipo della funzione richiamata all’avvio del programma sono definiti dall’implementazione.

  3. ISO 9899: 1999 5.1.2.2 Ambiente ospitato -> 5.1.2.2.1 Avvio del programma

    La funzione chiamata all’avvio del programma è denominata main. L’implementazione non dichiara alcun prototipo per questa funzione. Deve essere definito con un tipo restituito di int e senza parametri:

     int main(void) { /* ... */ } 

    o con due parametri (indicati qui come argc e argv, sebbene possano essere usati tutti i nomi, poiché sono locali alla funzione in cui sono dichiarati):

     int main(int argc, char *argv[]) { /* ... */ } 

    o equivalente; 9) o in qualche altro modo definito dall’implementazione.

  4. Razionale per gli standard internazionali – Linguaggi di programmazione – C, Revisione 5.10. 5.1.2.2 Ambiente ospitato -> 5.1.2.2.1 Avvio del programma

    Il comportamento degli argomenti su main e dell’interazione di exit, main e atexit (si veda §7.20.4.2) è stato codificato per limitare una varietà indesiderata nella rappresentazione delle stringhe argv e nel significato dei valori restituiti da main.

    La specifica di argc e argv come argomenti a main riconosce una vasta pratica precedente. argv [argc] deve essere un puntatore nullo per fornire un controllo ridondante per la fine dell’elenco, anche in base alla pratica comune.

    main è l’unica funzione che può essere dichiarata portabilmente o con zero o con due argomenti. (The number of other functions’ arguments must match exactly between invocation and definition.) This special case simply recognizes the widespread practice of leaving off the arguments to main when the program does not access the program argument strings. While many implementations support more than two arguments to main, such practice is neither blessed nor forbidden by the Standard; a program that defines main with three arguments is not strictly conforming (see §J.5.1.).

  5. ISO 9899:1999 5.1.2.2 Hosted environment –> 5.1.2.2.3 Program termination

    If the return type of the main function is a type compatible with int, a return from the initial call to the main function is equivalent to calling the exit function with the value returned by the main function as its argument;11) reaching the } that terminates the main function returns a value of 0. If the return type is not compatible with int, the termination status returned to the host environment is unspecified.

  6. ISO 9899:1999 5.1.2.1 Freestanding environment

    In a freestanding environment (in which C program execution may take place without any benefit of an operating system), the name and type of the function called at program startup are implementation-defined.

  7. ISO 9899:2011 5.1.2.2 Hosted environment -> 5.1.2.2.1 Program startup

    This section is identical to the C99 one cited above.

  8. ISO 9899:1999 5.1.2.1 Freestanding environment

    This section is identical to the C99 one cited above.

  9. ISO 14882:2003 3.6.1 Main function

    An implementation shall not predefine the main function. This function shall not be overloaded. It shall have a return type of type int, but otherwise its type is implementation-defined. All implementations shall allow both of the following definitions of main:

     int main() { /* ... */ } 

    e

     int main(int argc, char* argv[]) { /* ... */ } 
  10. ISO 14882:2003 3.6.1 Main function

    It is implementation-defined whether a program in a freestanding environment is required to define a main function.

  11. ISO 14882:2011 3.6.1 Main function

    An implementation shall not predefine the main function. This function shall not be overloaded. It shall have a return type of type int, but otherwise its type is implementation-defined. All implementations shall allow both

    — a function of () returning int and

    — a function of (int, pointer to pointer to char) returning int

    as the type of main (8.3.5).

  12. ISO 14882:2011 3.6.1 Main function

    This section is identical to the C++03 one cited above.

Keep in mind that,even though you’re returning an int, some OSes (Windows) truncate the returned value to a single byte (0-255).

main() in C89 and K&R C unspecified return types default to ‘int`.

 return 1? return 0? 
  1. If you do not write a return statement in int main() , the closing { will return 0 by default.

  2. return 0 or return 1 will be received by the parent process. In a shell it goes into a shell variable, and if you are running your program form a shell and not using that variable then you need not worry about the return value of main() .

See How can I get what my main function has returned? .

 $ ./a.out $ echo $? 

This way you can see that it is the variable $? which receives the least significant byte of the return value of main() .

In Unix and DOS scripting, return 0 on success and non-zero for error are usually returned. This is the standard used by Unix and DOS scripting to find out what happened with your program and controlling the whole flow.

The return value can be used by the operating system to check how the program was closed.

Return value 0 usually means OK in most operating systems (the ones I can think of anyway).

It also can be checked when you call a process yourself, and see if the program exited and finished properly.

It’s NOT just a programming convention.

The return value of main() shows how the program exited. If the return value is zero it means that the execution was successful while any non-zero value will represent that something went bad in the execution.

I was under the impression that standard specifies that main doesn’t need a return value as a successful return was OS based (zero in one could be either a success or a failure in another), therefore the absence of return was a cue for the compiler to insert the successful return itself.

However I usually return 0.

Returning 0 should tell the programmer that the program has successfully finished the job.

What to return depends on what you want to do with the executable. For example if you are using your program with a command line shell, then you need to return 0 for a success and a non zero for failure. Then you would be able to use the program in shells with conditional processing depending on the outcome of your code. Also you can assign any nonzero value as per your interpretation, for example for critical errors different program exit points could terminate a program with different exit values , and which is available to the calling shell which can decide what to do by inspecting the value returned. If the code is not intended for use with shells and the returned value does not bother anybody then it might be omitted. I personally use the signature int main (void) { .. return 0; .. }

If you really have issues related to efficiency of returning an integer from a process, you should probably avoid to call that process so many times that this return value becomes an issue.

If you are doing this (call a process so many times), you should find a way to put your logic directly inside the caller, or in a DLL file, without allocate a specific process for each call; the multiple process allocations bring you the relevant efficiency problem in this case.

In detail, if you only want to know if returning 0 is more or less efficient than returning 1, it could depend from the compiler in some cases, but generically, assuming they are read from the same source (local, field, constant, embedded in the code, function result, etc.) it requires exactly the same number of clock cycles.

In C++ the main function should be declared as int main() and not void main() as the compiler then throws an error in the case of void main. The main function can take any number of arguments like int main(int k,int l,int arr[]) or int main(void).

 #include  using namespace std; int main(void) { // your code goes here cout< <"a"; return 0; } 

Produzione:

 Success #stdin #stdout 0s 4416KB a 

Coming to the return part it should return only 0 else the compiler throws an error. for example if you return 1,you will get the desired output but it also throws a runtime error.

Esempio

 #include  using namespace std; int main(int k,float m,char g, int arr[]) { // your code goes here k=0; cout<  

Produzione:

 Runtime error #stdin #stdout 0s 4448KB 0aa 

Here is a small demonstration of the usage of return codes…

When using the various tools that the Linux terminal provides one can use the return code for example for error handling after the process has been completed. Imagine that the following text file myfile is present:

This is some example in order to check how grep works.

When you execute the grep command a process is created. Once it is through (and didn’t break) it returns some code between 0 and 255. For example:

 $ grep order myfile 

If you do

 $ echo $? $ 0 

you will get a 0. Why? Because grep found a match and returned an exit code 0, which is the usual value for exiting with a success. Let’s check it out again but with something that is not inside our text file and thus no match will be found:

 $ grep foo myfile $ echo $? $ 1 

Since grep failed to match the token “foo” with the content of our file the return code is 1 (this is the usual case when a failure occurs but as stated above you have plenty of values to choose from).

Now the following bash script (simply type it in a Linux terminal) although very basic should give some idea of error handling:

 $ grep foo myfile $ CHECK=$? $ [ $CHECK -eq 0] && echo 'Match found' $ [ $CHECK -ne 0] && echo 'No match was found' $ No match was found 

After the second line nothing is printed to the terminal since “foo” made grep return 1 and we check if the return code of grep was equal to 0. The second conditional statement echoes its message in the last line since it is true due to CHECK == 1.

As you can see if you are calling this and that process it is sometimes essential to see what it has returned (by the return value of main()).

Omit return 0

When a C or C++ program reaches the end of main the compiler will automatically generate code to return 0, so there is no need to put return 0; explicitly at the end of main .

Note: when I make this suggestion, it’s almost invariably followed by one of two kinds of comments: “I didn’t know that.” or “That’s bad advice!” My rationale is that it’s safe and useful to rely on compiler behavior explicitly supported by the standard. For C, since C99; see ISO/IEC 9899:1999 section 5.1.2.2.3:

[…] a return from the initial call to the main function is equivalent to calling the exit function with the value returned by the main function as its argument; reaching the } that terminates the main function returns a value of 0.

For C++, since the first standard in 1998; see ISO/IEC 14882:1998 section 3.6.1:

If control reaches the end of main without encountering a return statement, the effect is that of executing return 0;

All versions of both standards since then (C99 and C++98) have maintained the same idea. We rely on automatically generated member functions in C++, and few people write explicit return; statements at the end of a void function. Reasons against omitting seem to boil down to “it looks weird” . If, like me, you’re curious about the rationale for the change to the C standard read this question . Also note that in the early 1990s this was considered “sloppy practice” because it was undefined behavior (although widely supported) at the time.

So I advocate omitting it; others disagree (often vehemently!) In any case, if you encounter code that omits it, you’ll know that it’s explicitly supported by the standard and you’ll know what it means.

What is the correct (most efficient) way to define the main() function in C and C++ — int main() or void main() — and why?

Those words “(most efficient)” don’t change the question. Unless you’re in a freestanding environment, there is one universally correct way to declare main() , and that’s as returning int.

What should main() return in C and C++?

It’s not what should main() return, it’s what does main() return. main() is, of course, a function that someone else calls. You don’t have any control over the code that calls main() . Therefore, you must declare main() with a type-correct signature to match its caller. You simply don’t have any choice in the matter. You don’t have to ask yourself what’s more or less efficient, or what’s better or worse style, or anything like that, because the answer is already perfectly well defined, for you, by the C and C+ standards. Just follow them.

If int main() then return 1 or return 0?

0 for success, nonzero for failure. Again, not something you need to (or get to) pick: it’s defined by the interface you’re supposed to be conforming to.

This basically depends on your execution environment (the OS). C implies that it will be run by a UNIX like OS which expects the program to return a (small? 1 Byte? can’t remember) integer to indicate success / failure.

You should probably just use int main(int argc, char** argv) .