Considera queste due definizioni di funzione:
void foo() { }
void foo(void) { }
C'è qualche differenza tra questi due? In caso contrario, perché l' void
argomento è lì? Ragioni estetiche?
Considera queste due definizioni di funzione:
void foo() { }
void foo(void) { }
C'è qualche differenza tra questi due? In caso contrario, perché l' void
argomento è lì? Ragioni estetiche?
Risposte:
In C :
void foo()
significa "una funzione foo
che accetta un numero non specificato di argomenti di tipo non specificato" void foo(void)
significa "una funzione foo
che non accetta argomenti"In C ++ :
void foo()
significa "una funzione foo
che non accetta argomenti" void foo(void)
significa "una funzione foo
che non accetta argomenti"Scrivendo foo(void)
, quindi, otteniamo la stessa interpretazione in entrambe le lingue e rendiamo le nostre intestazioni multilingue (anche se di solito abbiamo bisogno di fare qualche altra cosa alle intestazioni per renderle veramente cross-language; vale a dire, avvolgerle in un extern "C"
se stiamo compilando C ++).
void
, allora avrebbe potuto evitare il problema di "analisi più irritante".
void foo()
era l'unica sintassi per dichiarare una funzione. Quando sono state introdotte le firme, il comitato C ha dovuto chiarire la mancanza di parametri dalla vecchia sintassi e ha introdotto la void foo(void)
sintassi. C ++ lo prese per motivi di compatibilità.
void foo()
posto di void foo(void)
produce una differenza funzionale? Cioè sto usando la versione senza il vuoto da molti anni e non ho visto alcun problema, mi sto perdendo qualcosa?
void foo() { if ( rand() ) foo(5); }
compila ed esegue (causando un comportamento indefinito a meno che tu non sia molto fortunato), mentre void foo(void)
con lo stesso corpo causerebbe un errore di compilazione.
Mi rendo conto che la tua domanda riguarda C ++, ma quando si tratta di C la risposta può essere trovata in K&R, pagine 72-73:
Inoltre, se una dichiarazione di funzione non include argomenti, come in
double atof();
anche questo significa che non si deve presumere nulla sugli argomenti di atof; tutto il controllo dei parametri è disattivato. Questo significato speciale dell'elenco di argomenti vuoto ha lo scopo di consentire ai programmi C meno recenti di essere compilati con nuovi compilatori. Ma è una cattiva idea usarlo con nuovi programmi. Se la funzione accetta argomenti, dichiarali; se non accetta argomenti, usa void.
Bozza standard C ++ 11 N3337
Non c'è differenza.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf
Allegato C "Compatibilità" C.1.7 Clausola 8: i dichiaranti dichiarano:
8.3.5 Modifica: in C ++, una funzione dichiarata con un elenco di parametri vuoto non accetta argomenti. In C, un elenco di parametri vuoto significa che il numero e il tipo degli argomenti della funzione sono sconosciuti.
Esempio:
int f(); // means int f(void) in C ++ // int f( unknown ) in C
Motivazione: Questo serve ad evitare chiamate di funzioni errate (cioè chiamate di funzioni con il numero o il tipo di argomenti sbagliati).
Effetto sulla funzione originale: passa alla semantica della funzione ben definita. Questa funzione è stata contrassegnata come "obsoleta" in C.
8.5.3 dice:
4. La clausola di dichiarazione dei parametri determina gli argomenti che possono essere specificati e la loro elaborazione quando viene chiamata la funzione. [...] Se la clausola di dichiarazione dei parametri è vuota, la funzione non accetta argomenti. L'elenco dei parametri (vuoto) equivale all'elenco dei parametri vuoto.
C99
Come menzionato da C ++ 11, int f()
non specifica nulla sugli argomenti ed è obsoleto.
Può portare a codice funzionante o UB.
Ho interpretato in dettaglio lo standard C99 su: https://stackoverflow.com/a/36292431/895245
In C, si usa un vuoto in un riferimento di funzione vuoto in modo che il compilatore abbia un prototipo e che il prototipo non abbia "nessun argomento". In C ++, non devi dire al compilatore che hai un prototipo perché non puoi tralasciare il prototipo.