Quelle est la difference entre function () et function (void)?

28

J'ai entendu dire que c'est une bonne pratique d'écrire des fonctions qui ne reçoivent rien en tant que paramètre comme ceci:

int func(void);

Mais j'entends que la bonne façon d'exprimer cela est comme ceci:

int func();

Quelle est la différence entre ces deux déclarations de fonction en C et C ++?

Grisonnant
la source
5
Ceci est un doublon de mille autres questions sur le réseau du site, entre autres stackoverflow.com/questions/18167390/…
Lars Viklund
@LarsViklund ce n'est qu'un doublon s'il y a une question sur ce site. Je ne peux pas en trouver un, donc indépendamment de ce qui est sur SO, ce n'est pas un doublon. Il vaut probablement la peine de garder cette question comme un panneau si rien d'autre.
1
@LightnessRacesinOrbit nous avons discuté dans le chat et avons décidé de le garder avec quelques modifications.

Réponses:

17

C et C ++ sont différents à cet égard.

Norme en ligne C 2011

6.7.6.3 Déclarateurs de fonctions (y compris les prototypes)
...
10 Le cas particulier d'un paramètre de type sans nom voidcomme seul élément de la liste spécifie que la fonction n'a pas de paramètres.
...
14 Une liste d'identifiants ne déclare que les identifiants des paramètres de la fonction. 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. La liste vide dans un déclarant de fonction qui ne fait pas partie d'une définition de cette fonction spécifie qu'aucune information sur le nombre ou les types de paramètres n'est fournie. 145)

En bref, une liste de paramètres vide dans une déclaration de fonction indique que la fonction prend un nombre non spécifié de paramètres, tandis qu'une liste de paramètres vide dans une définition de fonction indique que la fonction ne prend aucun paramètre.

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

En ce qui concerne C, vous ne devez jamais utiliser une liste d'identificateurs vide dans une déclaration ou une définition de fonction. Si une fonction n'est pas destinée à prendre des paramètres, spécifiez cela en utilisant voiddans la liste des paramètres.

Norme C ++ en ligne

8.3.5 Fonctions [dcl.fct]
...
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. [ Remarque: la clause de déclaration de paramètre est utilisée pour convertir les arguments spécifiés lors de l'appel de fonction; voir 5.2.2. - note de fin ] Si la clause de déclaration de paramètre est vide, la fonction ne prend aucun argument. Une liste de paramètres constituée d'un seul paramètre sans nom de type non dépendant voidéquivaut à une liste de paramètres vide. À l'exception de ce cas spécial, un paramètre ne doit pas avoir de type cv void. Si la clause de déclaration de paramètre termine par des points de suspension ou un pack de paramètres de fonction (14.5.3), le nombre d'arguments doit être égal ou supérieur au nombre de paramètres qui n'ont pas d'argument par défaut et ne sont pas des packs de paramètres de fonction. Où syntaxiquement correct et où «...» ne fait pas partie d'un déclarant abstrait , «, ...» est synonyme de «...». [ Exemple: la déclaration
    int printf(const char*, ...);
déclare une fonction qui peut être appelée avec différents nombres et types d'arguments.
    printf("hello world");
    printf("a=%d b=%d", a, b);
Cependant, le premier argument doit être d'un type qui peut être converti en un const char*- exemple final ] [ Note: L' en- tête standard <cstdarg>contient un mécanisme d'accès des arguments en utilisant le passé des points de suspension (voir 5.2.2 et 18.10). - note de fin ]

Dans le cas de C ++, une liste de paramètres vide dans une déclaration ou une définition indique que la fonction ne prend aucun argument et équivaut à utiliser une liste de paramètres de void.

John Bode
la source
35

En C, une fonction avec une liste de paramètres vide ()peut prendre n'importe quoi pour ses arguments. Littéralement n'importe quoi. Ceci est généralement utilisé pour implémenter une fonction qui peut prendre un nombre variable d'arguments , bien que ces jours-ci, il soit préférable d'utiliser la syntaxe d'ellipse plus explicite (...)pour ces fonctions.

En C, une fonction avec la liste des paramètres (void)prend explicitement rien pour ses arguments. Cela signifie que le compilateur peut vous dire que vous avez fait une erreur si vous essayez de passer quelque chose.

En C ++, ces déclarations de fonctions sont équivalentes. Une liste de paramètres vide signifie "pas de paramètres" de la même manière voidque.

Ixrec
la source
Re: "Ceci est généralement utilisé pour implémenter une fonction qui peut prendre un nombre variable d'arguments": en êtes-vous sûr? Je ne pense pas avoir jamais vu de programme utilisant des listes de paramètres explicites pour les déclarations directes de fonctions non variadiques et ()pour celles de fonctions variadiques. Avez-vous un exemple de programme qui utilise cette convention?
ruakh
4
La fonction variadic AC doit être définie avec la ...syntaxe et doit avoir au moins un paramètre nommé. La définition d'une telle fonction avec ()un comportement indéfini - et il n'y a aucun moyen pour le corps de la fonction d'utiliser les macros définies dans <stdarg.h>pour lire les valeurs des paramètres. C'est le cas depuis la norme 1989/1990.
Keith Thompson
@KeithThompson: Cette question et cette réponse parlent de prédéclarations, pas de définitions de fonctions.
ruakh
3
@ruakh: Une fonction variadique doit être déclarée et définie à l'aide de la ...syntaxe pour éviter un comportement indéfini.
Keith Thompson