2009-11-19 11 views
9

Lo standard C dice:dichiarando correttamente la funzione main() in ANSI C

La funzione chiamata all'avvio del programma prende il nome principale. L'implementazione non dichiara alcun prototipo per questa funzione . Essa è definita con un tipo ritorno di int e senza parametri:

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

o con due parametri (di cui qui come argc e argv, se eventuali nomi possono essere utilizzati, in quanto sono locali alla funzione in cui sono dichiarate ):

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

o equivalente o in qualche altro modo implementazione definita.

Tuttavia, Kernighan & Ritchie nella loro seconda edizione (la canonica ANSI C) bibbia basta usare:

main() 
{ 
    /* taram pampam ... */ 

    return 0; 
} 

Chi ha ragione? Ha a che fare con la funzione senza il valore di ritorno che assume automaticamente il ritorno int in C?

risposta

14

Bene, se si desidera ANSI C, quindi per definizione lo standard è giusto.

In C89/C90 è implicito il tipo di ritorno int, pertanto la definizione K & R è accettabile.

Nel C99 questo non è più il caso.

Lo standard C90 è la seguente dicitura (5.1.2.2.1 all'avvio del programma), che è molto simile al testo C99 (probabilmente la maggior parte in modo significativo si utilizza il meno forte 'puo' invece di 'deve'):

La funzione richiamata all'avvio del programma è denominata main. L'implementazione non dichiara alcun prototipo per questa funzione. Si può definire senza parametri:

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

o con due parametri (qui indicati come argc e argv, se tutti i nomi possono essere utilizzati, in quanto sono locali alla funzione in cui sono dichiarate):

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

Se vengono definiti i parametri della funzione main devono rispettare i seguenti vincoli:

[etc. ...]

Non c'è niente in quella sezione direttamente sul fatto che se si omette il tipo di reso, il valore predefinito sarà int.

Francamente, ho difficoltà a trovare esattamente dove tale comportamento è specificato dallo standard. Il più vicino che posso venire è in 6.7.1 (funzioni definizioni) dove la grammatica di definizioni di funzioni indica che la «Dichiarazione-specificatori sono opzionali, e gli esempi dicono:

Esempi:

  1. Nel seguente:

    extern int max(int a, int b) 
        { 
         return a > b ? a : b; 
        } 
    

    extern è l'identificatore della classe di archiviazione e int è l'identificatore del tipo (ognuno dei quali può essere omesso in quanto tali sono i valori predefiniti) ...

+0

oh, non conoscevano la differenza tra 99 e 89 qui, forse questa è la ragione perché io citando da 99! Hai lo standard 89/90 e puoi citare il paragrafo parallelo su main da esso? – zaharpopov

+0

Lo standard C89 ha detto più o meno la stessa cosa; ma in C89, una funzione senza un tipo di ritorno esplicito è stata implicitamente presupposta per restituire int, quindi la forma int-less era equivalente. –

+0

@zaharpopov - Ho aggiunto dettagli del vecchio standard. –

3

Sì, in C89 (lo standard C originale), se una funzione è dichiarata senza un tipo di ritorno, si presume per tornare int. C99 richiede un tipo di ritorno esplicito su tutte le funzioni.

+0

ma la loro definizione non viola lo standard in qualche modo, comunque? – zaharpopov

+0

No. Se implichi un int lì, allora corrisponde alle definizioni accettabili di main. – GManNickG

+2

Zaharpopov: La loro definizione era legale (e l'autorità) in quel momento. C99 (che è venuto dopo) ora proibisce i tipi di ritorno implicito int. –

3

Inoltre, c'è una sottile differenza (almeno nelle dichiarazioni) tra main() e main (void) -

main() 

è una funzione (implicitamente) la restituzione int e prendendo un non specificato numero di argomenti

main(void) 

prende non argomenti.

+2

Questo è solo in una dichiarazione - e non conosco nessuno che dichiari main(). In una definizione, i due sono equivalenti, anche se la notazione esplicita 'int main (void)' è generalmente lo stile C migliore; in C++, omettere il 'vuoto' è perfettamente accettabile. –

+1

Ho modificato il mio post per riflettere questo. Mentre potrebbe non essere il caso in main in particolare, vale la pena notare questo per altre funzioni ... –

0

La versione di K & R I è stata stampata nel 1988. Lo standard non era ancora disponibile, quindi ci sono alcune incongruenze. Tuttavia, la maggior parte della 2a edizione è conforme allo standard C89.

Ho trovato un text version of the C89 Standard (YAY per Google); si dice:

"all'avvio del programma"

La funzione chiamata al programma all'avvio prende il nome principale. L'implementazione non dichiara il prototipo per questa funzione. Si può definire senza parametri:

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

o con due parametri (di cui qui come argc e argv, se eventuali nomi possono essere utilizzati, in quanto sono locali alla funzione in cui sono dichiarati):

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

Penso che K & R2 sia uscito nel 1988, non solo la tua versione. – zaharpopov