Qual è la differenza tra function () e function (void)?


27

Ho sentito che è una buona pratica scrivere funzioni che non ricevono nulla come parametro come questo:

int func(void);

Ma ho sentito che il modo giusto di esprimerlo è così:

int func();

Qual è la differenza tra queste due dichiarazioni di funzioni in C e C ++?


5
Questo è un duplicato di mille altre domande sulla rete del sito, tra gli altri stackoverflow.com/questions/18167390/...
Lars Viklund

@LarsViklund è solo un duplicato se c'è una domanda su questo sito. Non riesco a trovarne uno, quindi indipendentemente da ciò che è in SO, questo non è un duplicato. Probabilmente vale la pena tenere questa domanda come un cartello se non altro.


1
@LightnessRacesinOrbit abbiamo discusso in chat e abbiamo deciso di tenerlo in giro con alcune modifiche.

Risposte:


17

C e C ++ sono diversi sotto questo aspetto.

C 2011 Standard online

6.7.6.3 Dichiaratori di funzioni (compresi i prototipi)
...
10 Il caso speciale di un parametro senza nome di tipo voidcome unico elemento nell'elenco specifica che la funzione non ha parametri.
...
14 Un elenco di identificatori dichiara solo gli identificatori dei parametri della funzione. Un elenco vuoto in un dichiaratore di funzione che fa parte di una definizione di tale funzione specifica che la funzione non ha parametri. L'elenco vuoto in un dichiaratore di funzione che non fa parte di una definizione di tale funzione specifica che non vengono fornite informazioni sul numero o sui tipi di parametri. 145)

In breve, un elenco di parametri vuoto in una dichiarazione di funzione indica che la funzione accetta un numero non specificato di parametri, mentre un elenco di parametri vuoto in una definizione di funzione indica che la funzione non accetta parametri.

T foo( void ); // declaration, foo takes no parameters
T bar();       // declaration, bar takes an *unspecified* number of parameters

T foo( void ) { ... } // definition, foo takes no parameters
T bar() { ... }       // definition, bar takes no parameters

Per quanto riguarda C, non si dovrebbe mai usare un elenco di identificatori vuoto in una dichiarazione o definizione di funzione. Se una funzione non è destinata ad accettare alcun parametro, specificarlo utilizzando voidnell'elenco dei parametri.

Standard C ++ online

8.3.5 Funzioni [dcl.fct]
...
4 La clausola parametro-dichiarazione- determina gli argomenti che possono essere specificati e la loro elaborazione quando viene chiamata la funzione. [ Nota: la clausola di dichiarazione dei parametri viene utilizzata per convertire gli argomenti specificati nella chiamata di funzione; vedi 5.2.2. - end note ] Se la clausola parametro-dichiarazione- è vuota, la funzione non accetta argomenti. Un elenco di parametri costituito da un singolo parametro senza nome di tipo non dipendente voidequivale a un elenco di parametri vuoto. Tranne questo caso speciale, un parametro non deve avere tipo cv void. Se la clausola di dichiarazione dei parametritermina con un puntino di sospensione o un pacchetto di parametri di funzione (14.5.3), il numero di argomenti deve essere uguale o maggiore del numero di parametri che non hanno un argomento predefinito e non sono pacchetti di parametri di funzione. Dove sintatticamente corretto e dove "..." non fa parte di un dichiaratore astratto , ", ..." è sinonimo di "...". [ Esempio: la dichiarazione
    int printf(const char*, ...);
dichiara una funzione che può essere chiamata con vari numeri e tipi di argomenti.
    printf("hello world");
    printf("a=%d b=%d", a, b);
Tuttavia, il primo argomento deve essere di un tipo che può essere convertito in un esempioconst char* - end ] [ Nota: l'intestazione standard <cstdarg>contiene un meccanismo per accedere agli argomenti passati usando i puntini di sospensione (vedere 5.2.2 e 18.10). - nota finale ]

Nel caso di C ++, un elenco di parametri vuoto in una dichiarazione o una definizione indica che la funzione non accetta argomenti ed è equivalente all'utilizzo di un elenco di parametri di void.


35

In C, una funzione con un elenco di parametri vuoto ()può accettare qualsiasi cosa per i suoi argomenti. Letteralmente qualsiasi cosa. Questo di solito viene utilizzato per implementare una funzione che può richiedere un numero variabile di argomenti , anche se in questi giorni è preferibile utilizzare la sintassi più ellittica esplicita (...)per queste funzioni.

In C, una funzione con l'elenco dei parametri (void)accetta esplicitamente nulla per i suoi argomenti. Ciò significa che il compilatore può effettivamente dirti che hai fatto un errore se provi a passare qualcosa.

In C ++, queste dichiarazioni di funzioni sono equivalenti. Un elenco di parametri vuoto significa "nessun parametro" come voidfa.


Ri: "Questo è di solito usato per implementare una funzione che può accettare un numero variabile di argomenti": Ne sei sicuro? Non credo di aver mai visto un programma che utilizzava elenchi di parametri espliciti per dichiarazioni in avanti di funzioni non variabili e ()per quelle di variabili variabili. Hai un esempio di un programma che utilizza questa convenzione?
Ruakh,

4
La funzione variadica CA deve essere definita con la ...sintassi e deve avere almeno un parametro denominato. Definire una tale funzione con ()causa un comportamento indefinito - e non c'è modo per il corpo della funzione di usare le macro definite <stdarg.h>per leggere i valori dei parametri. Questo è stato il caso dallo standard 1989/1990.
Keith Thompson,

@KeithThompson: questa domanda e questa risposta parlano di predeclarations, non di definizioni di funzioni.
Ruakh,

3
@ruakh: una funzione variadica deve essere dichiarata e definita usando la ...sintassi per evitare comportamenti indefiniti.
Keith Thompson,
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.