est f (void) déconseillé dans les versions C et C ++ modernes

Je suis actuellement en train de refactoriser / ranger un ancien code C utilisé dans un projet C ++ et de voir régulièrement des fonctions telles que:

int f(void) 

que j’aurais tendance à écrire comme:

 int f() 

Y a-t-il une raison de ne pas remplacer (void) par () dans le code afin d’améliorer la cohérence, ou existe-t-il une différence subtile entre les deux dont je ne suis pas conscient? Plus précisément, si une fonction de membre virtuel en C ++ est décrite comme:

 virtual int f(void) 

et une classe dérivée comprend une fonction membre:

 int f() 

est-ce un remplacement valide? De plus, suis-je susceptible de rencontrer des problèmes de lieur basés sur des signatures presque identiques?

En C, la déclaration int f(void) signifie une fonction renvoyant int qui ne prend aucun paramètre. La déclaration int f() signifie une fonction renvoyant int qui prend un nombre quelconque de parameters. Ainsi, si vous avez une fonction qui ne prend aucun paramètre en C, le premier est le prototype correct.

En C ++, je crois que int f(void) est obsolète, et int f() est préférable, car il signifie spécifiquement une fonction qui ne prend aucun paramètre.

Pour append à la réponse de Chris, utiliser int f() est une mauvaise pratique en C, selon mon expérience, puisque vous perdez la capacité du compilateur à comparer la déclaration de la fonction à sa définition, pour vous assurer qu’elle sera appelée correctement.

Par exemple, le code suivant est conforme aux normes C:

 #include  void foo(); void bar(void) { foo(); } void foo(int a) { printf("%d\n", a); } 

Mais cela se traduit par un comportement indéfini, car aucun n’a été transmis à foo .

En C ++, il existe deux versions de foo : une qui ne prend aucun argument et l’autre qui prend un int . La bar finit donc par appeler la version non définie, ce qui entraînerait une erreur de l’éditeur de liens (en supposant qu’il n’y ait pas d’autres définitions de foo n’importe où).

Les réponses ci-dessus sont tout à fait correctes, mais je suis lié à l’excellente page de David Tribble car elle donne une bonne explication à ce sujet et à bien d’autres questions.

Les points forts:

C distingue une fonction déclarée avec une liste de parameters vide et une fonction déclarée avec une liste de parameters composée uniquement du vide. Le premier est une fonction non-typée prenant un nombre non spécifié d’arguments, tandis que le second est une fonction prototypée ne prenant aucun argument.

C ++, quant à lui, ne fait pas de distinction entre les deux déclarations et les considère comme une fonction ne prenant aucun argument.

Pour le code destiné à être compilé en C ou C ++, la meilleure solution à ce problème consiste à toujours déclarer les fonctions ne prenant aucun paramètre avec un prototype vide explicite.

Les prototypes de fonctions vides sont une fonctionnalité obsolète dans C99 (comme dans C89).

Edit: Après avoir examiné la norme, il est peut-être utile de noter que la syntaxe func (void) n’est pas obsolète en C ++, mais elle est généralement considérée comme un idiome de style C. Je pense que la plupart des programmeurs C ++ que j’ai rencontrés préfèrent la liste de parameters vide.

Edit 2: Ajouter une citation du standard C ++, section 8.3.5, paragraphe 2:

“Si la clause de déclaration de paramètre est vide, la fonction ne prend aucun argument. La liste de parameters (void) est équivalente à la liste de parameters vide. Sauf pour ce cas particulier, void ne doit pas être un type de paramètre , tels que vide *, peut). ”

Il n’y a aucune mention que l’une ou l’autre forme est déconseillée. Merci encore à l’excellent site Web de M. Tribble pour m’avoir indiqué la section correcte de la norme.

tl; dr: utiliser le void .

Compte tenu de la rétrocompatibilité en C ++ et du peu d’ambiguïté identifié ci-dessous, j’affirme que nous revenons à KnR et ANSI C pour une réponse définitive:

 int getline(void); int copy(void) 

Étant donné que les versions spécialisées de getline et copy n’ont aucun argument, la logique suggère que leurs prototypes au début du fichier doivent être getline() et copy() . Mais pour des raisons de compatibilité avec les anciens programmes C, la norme prend une liste vide en tant que déclaration de style ancien et désactive toute vérification de liste d’arguments; le mot void doit être utilisé pour une liste explicitement vide. [Kernighan & Richie, le langage de programmation C, 1988, pages 32 à 33]

et..

La signification spéciale de la liste d’arguments vide est destinée à permettre aux programmes C plus anciens de comstackr 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; si elle ne prend aucun argument, utilisez void [ibid, pg. 73]

EDIT: Interrompez le rest dans une discussion séparée ici: La spécification de l’utilisation de void dans la déclaration d’une fonction qui ne prend pas d’argument adresse-t-elle The Most Vexing Parse?

C11 N1570 projet standard

void f() est obsolète, void f(void) recommandé:

6.11.6 déclarateurs de fonctions :

1 L’utilisation de déclarateurs de fonctions avec des parenthèses vides (et non des déclarants de type paramètre au format prototype) est une fonctionnalité obsolète.

Introduction :

2 Certaines caractéristiques sont obsolètes, ce qui signifie qu’elles peuvent être retirées lors de futures révisions de la présente Norme internationale. Ils sont conservés en raison de leur utilisation généralisée, mais leur utilisation dans de nouvelles implémentations (pour les fonctionnalités d’implémentation) ou de nouveaux programmes (pour la langue [6.11] ou les fonctionnalités de bibliothèque [7.31]) est déconseillée.

Discussion détaillée: https://stackoverflow.com/a/36292431/895245

Projet standard C ++ 11 N3337

Ni void f(void) ni void f() sont dépréciés.

void f(void) existe pour la compatibilité avec C. Annexe C “Compatibility” C.1.7 Clause 8: déclarateurs :

8.3.5 Changement: en C ++, une fonction déclarée avec une liste de parameters vide ne prend aucun argument. En C, une liste de parameters vide signifie que le nombre et le type des arguments de la fonction sont inconnus.

Etant donné que void f() est obsolète dans C et void f(void) recommandé, void f(void) existera aussi longtemps que C ++ veut conserver la compatibilité.

void f(void) et void f() sont les mêmes en C ++. Donc, le plus long void f(void) n’a de sens que si vous tenez à écrire du code qui comstack en C et C ++, ce qui ne vaut probablement pas la peine.

Discussion détaillée: https://stackoverflow.com/a/36835303/895245

En C ++, int f(void) est en effet une déclaration obsolète qui est équivalente à 100% à int f() . C’est la même signature. Le void dans ce contexte est aussi important que, par exemple, les espaces. Cela signifie également qu’ils sont soumis à la règle de définition unique (ils ne sont pas surchargés) et que Derived::f(void) remplace Base::f() .

Ne plaisante pas avec des choses comme f(const void) , cependant. Il n’y a pas beaucoup de consensus sur ce que signifie ce genre d’étrangeté.