68 votes

f (void) est obsolète en C et C ++ modernes

Je suis en train de refactoring/la remise en place de certains vieux C code utilisé dans un projet C++, et de voir régulièrement fonctions telles que:

int f(void)

qui j'aurais tendance à écrire comme:

int f()

Est-il une raison de ne pas le remplacer (void) avec () tout au long de la base de code afin d'améliorer la cohérence, ou il y a une différence subtile entre les deux que je ne suis pas au courant? Plus précisément, si une fonction membre virtuelle en C++ est décrit comme:

virtual int f(void)

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

int f()

est-ce valable remplacer? En outre, je suis susceptible de rencontrer de linker des problèmes à partir de presque identiques signatures?

101voto

Chris Young Points 8525

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

En C ++, je pense que int f(void) est déconseillé et que int f() est préférable, car cela signifie spécifiquement une fonction qui ne prend aucun paramètre.

21voto

Zach Hirsch Points 5040

Pour ajouter à Chris de réponse, à l'aide de int f() est une mauvaise pratique en C, dans mon expérience, car vous perdez la capacité du compilateur pour comparer la déclaration de la fonction à sa définition, pour s'assurer qu'elle sera appelée correctement.

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

#include <stdio.h>
void foo();
void bar(void) {
    foo();
}
void foo(int a) {
    printf("%d\n", a);
}

Mais il en résulte un comportement indéfini, depuis a n'a pas été transmis à l' foo.

En C++, il existe deux versions de l' foo: celui qui ne prend pas d'arguments et qui prend un int. Donc, bar des vents jusqu'à l'appel de la indéfini version, qui pourraient résulter d'une erreur de l'éditeur de liens (en supposant que il n'y a pas d'autres définitions de l' foo n'importe où).

18voto

Dan Olson Points 11210

Les réponses ci-dessus sont tout à fait correct, mais je suis un lien vers David Tribble excellente page, car il donne une bonne explication sur ce et de nombreux autres problèmes.

Les points forts:

C fait la distinction entre une fonction déclarée avec un vide de la liste des paramètres et une fonction déclarée avec un liste des paramètres composé de seulement void. Le premier est une unprototyped fonction prenant un nombre non spécifié des arguments, tandis que le second est un prototype de la fonction à ne pas prendre de les arguments.

C++, d'autre part, ne fait pas de la distinction entre les deux les déclarations et les considère à la fois pour signifier une fonction ne prenant aucun les arguments.

Pour le code qui est destiné à être compilé comme le C ou le C++, le meilleur la solution à ce problème est de toujours déclarer des fonctions sans paramètres explicite nulle prototype.

Vide prototypes de fonction sont un fonctionnalité obsolète en C99 (comme ils ont été en C89).

Edit: Après avoir regardé la norme, c'est peut-être intéressant de noter que la touche func(void) la syntaxe est pas obsolète en C++, mais il est généralement considéré plus comme un style C idiome. Je pense que la plupart des programmeurs C++ j'ai couru à travers préfèrent le vide de la liste des paramètres.

Edit 2: Ajout d'une citation de la norme C++, section 8.3.5, paragraphe 2:

"Si le paramètre-déclaration de la clause est vide, la fonction ne prend pas d'arguments. La liste des paramètres (void) est l'équivalent de la vide de la liste des paramètres. À l'exception de ce cas particulier, nulle ne doit pas être un paramètre de type (bien que les types dérivés de vide, comme void*)."

Il n'y a aucune mention du fait que le formulaire est obsolète. Merci encore à M. Tribble l'excellent site pour m'indiquer la bonne section de la norme.

-1voto

MSalters Points 74024

En C ++, int f (void) est en effet une déclaration déconseillée équivalent à 100% à int f (). Il est la même signature. Les void dans ce contexte sont aussi significatifs que par exemple les espaces blancs. Cela signifie également qu'ils sont soumis à la règle de définition unique (ils ne surchargent pas) 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 genre de bizarreries.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X