C'è una differenza tra foo (void) e foo () in C ++ o C?


253

Considera queste due definizioni di funzione:

void foo() { }

void foo(void) { }

C'è qualche differenza tra questi due? In caso contrario, perché l' voidargomento è lì? Ragioni estetiche?


Per C il Q / A è qui
Antti Haapala

Risposte:


317

In C :

  • void foo()significa "una funzione fooche accetta un numero non specificato di argomenti di tipo non specificato"
  • void foo(void)significa "una funzione fooche non accetta argomenti"

In C ++ :

  • void foo()significa "una funzione fooche non accetta argomenti"
  • void foo(void)significa "una funzione fooche 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 ++).


10
Ma se C ++ avesse richiesto il void, allora avrebbe potuto evitare il problema di "analisi più irritante".
Adrian McCarthy,

5
È vero, ma ci sono così tante altre analisi scadenti in C ++ che non ha senso nel kvetching su ognuna di esse.
DrPizza

16
Su una domanda recente, @James Kanze ha pubblicato una notizia interessante. Ripubblicare qui per evitare di perderlo: le prime versioni di C non permettevano di specificare il numero di parametri che una funzione poteva prendere, quindi 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à.
Matthieu M.

3
Potete darmi un esempio di C C90 e versioni successive in cui l'utilizzo al 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?
Chacham15,

6
@ chacham15 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.
MM

39

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.


Ma la domanda riguarda le definizioni, in tal caso la regola C pertinente è Un elenco vuoto in un dichiaratore di funzione che fa parte di una definizione di tale funzione specifica che la funzione non ha parametri.
jinawee,

9

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


2

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.


1
"prototipo" indica la dichiarazione dell'elenco di argomenti e il tipo restituito. Lo dico perché "prototipo" mi ha confuso su cosa intendevi inizialmente.
Zan Lynx,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.