web-dev-qa-db-fra.com

Différence entre int main () et int main (vide)?

Que signifie ce qui suit: 

int main(void) {...} 

CONTRE

int main() {...}

?

Je pense que int main() {...} signifie que main ne reçoit aucun paramètre (en ligne de commande), cependant:

int main(int argc, char *argv[])

est-ce que.

Mais que signifie int main(void) {...}? que signifie void?

J'ai regardé ici mais c'est en quelque sorte une question différente. 

55
ron

En C++, il n'y a pas de différence.


En C, la différence est discutable. Certains aiment dire que cette dernière version (celle sans void) est techniquement une extension d'implémentation commune et que le standard ne garantit pas son bon fonctionnement à cause du libellé de la norme. Cependant, la norme indique clairement que dans une définition de fonction, un ensemble vide de paramètres a un comportement bien défini: la fonction ne prend aucun paramètre. Ainsi, une telle définition de main correspond à la description suivante de la norme:

Il [main] doit être défini avec un type de retour int et sans paramètre. 

Il existe toutefois une différence notable entre les deux: à savoir, la version sans void ne fournit pas un prototype correct pour la fonction:

// this is OK.
int main()
{
  if (0) main(42);
}

// this requires a diagnostic to be shown during compiling
int main(void)
{
  if (0) main(42);
}

Oh, et pour compléter, la void a la signification suivante dans tous les déclarateurs de fonctions:

(6.7.6.3p10) Le cas particulier d'un paramètre non nommé de type void, unique élément de la liste, indique que la fonction n'a pas de paramètre.

50
eq-

En C, dans un prototype (mais pas en C++), une liste d'arguments vide signifie que la fonction peut prendre des arguments tout (dans la définition d'une fonction, cela signifie qu'aucun argument n'est utilisé). En C++, une liste de paramètres vide ne signifie aucun argument. En C, pour ne pas avoir d'argument, vous devez utiliser void. Voir this question pour une meilleure explication.

6
Linuxios

En C++, avoir une fonction foo(void) et foo() est la même chose. Cependant, en C c'est différent: foo(void) est une fonction qui n'a pas d'argument, alors que foo() est une fonction avec des arguments non spécifiés.

4

En C++, il n'y a pas de différence, les deux sont identiques.

Les deux définitions fonctionnent également en C, mais la seconde définition avec void est considérée comme techniquement meilleure, car elle spécifie clairement que main ne peut être appelée sans aucun paramètre ..__ En C, si une signature de fonction ne spécifie aucun argument, cela signifie que la fonction peut être appelée avec un nombre quelconque de paramètres ou sans aucun paramètre. Par exemple, essayez de compiler et d’exécuter les deux programmes C suivants (n’oubliez pas d’enregistrer vos fichiers au format .c). 

3
Dila Gurung

Tout d'abord, il existe une différence entre ce qui est autorisé pour les systèmes hébergés et les systèmes autonomes, comme affiché ici .

Pour les systèmes hébergés, le démarrage du programme 5.1.2.2.1 s’applique:

La fonction appelée au démarrage du programme s'appelle main. L'implémentation déclare no prototype pour cette fonction. Il doit être défini avec un type de retour int et avec no paramètres:

int main(void)

... (plus de texte suit concernant les styles argv/argc etc.).

La partie intéressante est "sans paramètres". int main() et int main (void) sont actuellement équivalents, car ils sont tous deux des déclarateurs de fonctions et n'ont aucun paramètre. Ce qui suit s'applique (6.7.6.3):

10 Le cas particulier d'un paramètre non nommé de type void en tant qu'élément unique de la liste indique que la fonction n'a pas de paramètre.

/ - /

14 Une liste d'identifiants ne déclare que les identifiants des paramètres de la fonction. Un vide liste dans un déclarateur de fonction qui fait partie d'une définition de cette fonction spécifie que le fonction n'a pas de paramètres. La liste vide dans un déclarateur de fonction qui ne fait pas partie d'un La définition de cette fonction ne spécifie aucune information sur le nombre ou les types de fichiers paramètres est fourni.145)

Je souligne surtout le texte en gras qui s'applique à int main(). Il y a aussi la note 145) à la fin du texte, où il est écrit "Voir les« instructions linguistiques futures »(6.11.6)":

6.11.6 Déclarateurs de fonction

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

Et voici la différence. En tant que déclarateur de fonction, int main() est bad style en raison de ce qui précède, car son fonctionnement dans la prochaine version de la norme C n'est pas garanti. Il est signalé comme une fonctionnalité obsolète dans C11.

Vous devez donc toujours utiliser int main (void) sur un système hébergé et jamais int main(), même si les deux formulaires sont, pour le moment, équivalents.


En C++, les deux formes sont complètement équivalentes, mais int main() est le style préféré pour des raisons esthétiques subjectives (Bjarne Stroustrup le dit ... ce qui est probablement une très mauvaise raison pour expliquer pourquoi vous faites quelque chose d'une manière particulière).

2
Lundin

En C++, il n'y a pas de différence entre les deux et int main() est une signature légale et un type de retour pour main.

1
juanchopanza

Je sais que le fil est vieux, mais cette question me dérangeait depuis un certain temps il y a quelques années, je voulais donc ajouter mon demi-cent (si ça).

Je traite toujours les fonctions C comme si elles avaient un nombre d'arguments fixe, quel que soit le contexte, à moins qu'elles n'utilisent va_args. C’est-à-dire que j’ai confiance de toujours avoir TOUJOURS le prototype:

int main(int argc, char **argv).

même si aucun argument n'est passé, la fonction a ces arguments sur la pile car la fonction principale n'a pas de surcharge de la fonction.

C a la capacité d’avoir une surcharge primitive en prétendant que l’argument n’est pas là. Dans ce cas, l'argument est toujours passé et se trouve sur la pile, mais vous n'y accédez jamais. Il réduit donc simplement la taille du code source.

Dire int main () signifie simplement que je sais que la fonction peut avoir des paramètres, mais que je ne les utilise pas, j'écris donc int main ().

Saying int main (void) dit que main CERTAINLY n'a pas d'argument et implique qu'il existe deux prototypes de fonctions différents:

int main(void);
int main(int argc, char **argv);

Puisque C n’a pas de surcharge de fonction, c’est un peu trompeur pour moi, et je me méfie du code qui contient le (vide) principal. Je ne le ferais pas si principal ne prenais JAMAIS aucun paramètre, auquel cas principal (vide) serait complètement OK.

REMARQUE: dans certaines implémentations, il y a plus de paramètres dans main que argc et argv, tels que env, mais cela ne me dérange pas car je sais que je ne dis pas explicitement que ce sont les deux seuls paramètres, mais ce sont les paramètres minimaux. et c'est bien d'avoir plus, mais pas moins. Ceci est en contraste avec le dire carrément int principal (vide) qui crie après moi car CETTE FONCTION N'A PAS DE PARAMÈTRES, ce qui n'est pas vrai, puisqu'elle le fait, ils sont simplement omis.

Voici mon code de base:

/* sample.c - build into sample. */
#include <stdio.h>

int main(void)
{
    int _argc = *((int *)2686800);
    char ***_pargv = (char ***)2686804;
    int i;

    for (i = 1; i < _argc; ++i) {
        printf("%s ", (*_pargv)[i]);
    }

    return 0;
}

./sample j'ai clairement des arguments

Il est clair que la fonction a des arguments qui lui ont été transmis, bien qu’elle se soit écartée pour dire explicitement que ce n’est pas le cas en tapant void dans le prototype de la fonction. 

Comme eq- dit ci-dessus:

(6.7.6.3p10) Le cas particulier d'un paramètre non nommé de type void comme seul élément dans la liste spécifie que la fonction n'a pas de paramètre.

Par conséquent, dire que la fonction a la valeur vide comme argument mais qu'il existe des arguments sur la pile est une contradiction.

Mon argument est que les arguments sont toujours là, affirmant ainsi explicitement que le principal est vide d’arguments est malhonnête. La manière honnête serait de dire int main (), qui ne dit rien sur le nombre de paramètres dont il dispose, mais uniquement sur le nombre de paramètres dont vous vous souciez.

NOTE2: Les variables _argc, _pargv dépendent du système. Pour trouver vos valeurs, vous devez les trouver en exécutant ce programme:

/* findargs.c */
#include <stdio.h>

int main(int argc, char **argv)
{
    printf("address of argc is %u.\n", &argc);
    printf("address of argv is %u.\n", &argv);

    return 0;
}

Ces valeurs doivent rester correctes pour votre système spécifique.

0
Dmitry

Le prototype de fonction ayant Type foo(void) est absolument identique à Type foo(), il n'y a pas de différence entre les deux. Former peut être utilisé pour la lisibilité.

Comme avec main - en prenant des arguments ou non, le programme peut toujours accéder aux informations en ligne de commande par d'autres moyens comme __argv, __argc, GetCommandLine ou d'autres symboles spécifiques à la plate-forme/compilateur.

0
Ajay