void foo()signifie "une fonction fooprenant un nombre non spécifié d'arguments de type non spécifié"
void foo(void)signifie "une fonction foone prenant aucun argument"
En C ++ :
void foo()signifie "une fonction foone prenant aucun argument"
void foo(void)signifie "une fonction foone prenant aucun argument"
En écrivant foo(void), par conséquent, nous obtenons la même interprétation dans les deux langues et rendons nos en-têtes multilingues (bien que nous ayons généralement besoin de faire plus de choses aux en-têtes pour les rendre vraiment multilingues; à savoir, les envelopper dans un extern "C"si nous compilons C ++).
Mais si C ++ avait exigé le void, il aurait pu éviter le problème de "l'analyse la plus vexante".
Adrian McCarthy
5
Certes, mais il y a tellement d'autres analyses merdiques en C ++, il n'y a vraiment aucun intérêt à en savoir plus sur l'une d'entre elles.
DrPizza
16
Sur une question récente, @James Kanze a publié une friandise intéressante. Republiez ici pour éviter de la perdre: les premières versions de C ne permettaient pas de spécifier le nombre de paramètres qu'une fonction pouvait prendre, void foo()c'était donc la seule syntaxe pour déclarer une fonction. Lorsque les signatures ont été introduites, le comité C a dû lever l'ambiguïté sans paramètre de l'ancienne syntaxe et a introduit la void foo(void)syntaxe. C ++ l'a pris pour des raisons de compatibilité.
Matthieu M.
3
Pouvez-vous me donner un exemple de C C90 et plus tard où l'utilisation void foo()au lieu de void foo(void)produira une différence fonctionnelle? C'est-à-dire que j'utilise la version sans vide depuis de nombreuses années et que je n'ai vu aucun problème, est-ce que je manque quelque chose?
chacham15
6
@ chacham15 void foo() { if ( rand() ) foo(5); } compile et s'exécute (provoquant un comportement indéfini sauf si vous êtes très chanceux), alors void foo(void)qu'avec le même corps, une erreur de compilation se produirait.
MM
39
Je sais que votre question concerne C ++, mais quand il s'agit de C, la réponse se trouve dans K&R, pages 72-73:
De plus, si une déclaration de fonction n'inclut pas d'arguments, comme dans
double atof();
cela signifie également qu'il ne faut rien présumer des arguments de atof; toute la vérification des paramètres est désactivée. Cette signification particulière de la liste d'arguments vide est destinée à permettre aux anciens programmes C de compiler avec de nouveaux compilateurs. Mais c'est une mauvaise idée de l'utiliser avec de nouveaux programmes. Si la fonction prend des arguments, déclarez-les; s'il ne prend aucun argument, utilisez void.
Mais la question porte sur les définitions, dans ce cas, la règle C pertinente est Une liste vide dans un déclarant de fonction qui fait partie d'une définition de cette fonction spécifie que la fonction n'a pas de paramètres.
Annexe C "Compatibilité" C.1.7 Article 8: déclarants dit:
8.3.5 Modification: en C ++, une fonction déclarée avec une liste de paramètres vide ne prend aucun argument. En C, une liste de paramètres vide signifie que le nombre et le type des arguments de fonction sont inconnus.
Exemple:
int f();// means int f(void) in C ++// int f( unknown ) in C
Justification: Cela permet d'éviter les appels de fonction erronés (c'est-à-dire les appels de fonction avec le mauvais nombre ou le mauvais type d'arguments).
Effet sur l'entité d'origine: modification de la sémantique d'une entité bien définie. Cette fonctionnalité a été marquée comme «obsolète» en C.
8.5.3 fonctions dit:
4. La clause de déclaration de paramètre détermine les arguments qui peuvent être spécifiés et leur traitement lors de l'appel de la fonction. [...] Si la clause de déclaration de paramètre est vide, la fonction ne prend aucun argument. La liste de paramètres (void) est équivalente à la liste de paramètres vide.
C99
Comme mentionné par C ++ 11, int f()ne spécifie rien sur les arguments et est obsolète.
En C, vous utilisez un vide dans une référence de fonction vide afin que le compilateur ait un prototype et que ce prototype n'ait "aucun argument". En C ++, vous n'avez pas besoin de dire au compilateur que vous avez un prototype car vous ne pouvez pas laisser de côté le prototype.
"prototype" signifie la déclaration de la liste d'arguments et le type de retour. Je dis cela parce que "prototype" m'a confus quant à ce que vous vouliez dire au début.
Réponses:
En C :
void foo()
signifie "une fonctionfoo
prenant un nombre non spécifié d'arguments de type non spécifié"void foo(void)
signifie "une fonctionfoo
ne prenant aucun argument"En C ++ :
void foo()
signifie "une fonctionfoo
ne prenant aucun argument"void foo(void)
signifie "une fonctionfoo
ne prenant aucun argument"En écrivant
foo(void)
, par conséquent, nous obtenons la même interprétation dans les deux langues et rendons nos en-têtes multilingues (bien que nous ayons généralement besoin de faire plus de choses aux en-têtes pour les rendre vraiment multilingues; à savoir, les envelopper dans unextern "C"
si nous compilons C ++).la source
void
, il aurait pu éviter le problème de "l'analyse la plus vexante".void foo()
c'était donc la seule syntaxe pour déclarer une fonction. Lorsque les signatures ont été introduites, le comité C a dû lever l'ambiguïté sans paramètre de l'ancienne syntaxe et a introduit lavoid foo(void)
syntaxe. C ++ l'a pris pour des raisons de compatibilité.void foo()
au lieu devoid foo(void)
produira une différence fonctionnelle? C'est-à-dire que j'utilise la version sans vide depuis de nombreuses années et que je n'ai vu aucun problème, est-ce que je manque quelque chose?void foo() { if ( rand() ) foo(5); }
compile et s'exécute (provoquant un comportement indéfini sauf si vous êtes très chanceux), alorsvoid foo(void)
qu'avec le même corps, une erreur de compilation se produirait.Je sais que votre question concerne C ++, mais quand il s'agit de C, la réponse se trouve dans K&R, pages 72-73:
la source
Projet standard C ++ 11 N3337
Il n'y a pas de différence.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf
Annexe C "Compatibilité" C.1.7 Article 8: déclarants dit:
8.5.3 fonctions dit:
C99
Comme mentionné par C ++ 11,
int f()
ne spécifie rien sur les arguments et est obsolète.Cela peut conduire à un code de travail ou à UB.
J'ai interprété la norme C99 en détail sur: https://stackoverflow.com/a/36292431/895245
la source
En C, vous utilisez un vide dans une référence de fonction vide afin que le compilateur ait un prototype et que ce prototype n'ait "aucun argument". En C ++, vous n'avez pas besoin de dire au compilateur que vous avez un prototype car vous ne pouvez pas laisser de côté le prototype.
la source