La fonction main () définie sans type de retour donne un avertissement

Ceci est mon programme:

main() { printf("hello world\n"); } 

Je reçois cet avertissement lors de la compilation:

 function should return a value 

Lorsque vous modifiez main() pour void main() , l’avertissement disparaît.

Pourquoi est-ce si?

Il y a peu de choses dont vous devriez prendre note:

  1. int est le type de retour de la fonction main() . Cela signifie que le genre de valeur que main() peut renvoyer est un entier.
  2. main( ) été toléré par les compilateurs C90 mais pas par les compilateurs C99, ce qui signifie qu’il ne fait plus partie de la norme C99. Ne le faites pas.
  3. void main() n’est pas un formulaire standard, certains compilateurs le permettent, mais aucune des normes ne l’a jamais répertorié en tant qu’option. Par conséquent, les compilateurs ne doivent pas accepter ce formulaire et plusieurs ne le font pas. Encore une fois, respectez le formulaire standard et vous ne rencontrerez aucun problème si vous déplacez un programme d’un compilateur à un autre.
  4. Et une dernière chose, au lieu d’écrire principal comme ceci:

    int main() // vous ne dites pas qu’il est possible de passer des arguments à main, ce qui signifie qu’il peut prendre ou non des arguments

écris comme ceci:

 int main(void)// this specifies there are no arguments taken by main 

Vous voudrez peut-être consulter la norme C99 pour plus de détails .

Résumé rapide: Si vous ne souhaitez pas utiliser d’arguments de ligne de commande, vous devez écrire:

 int main(void) { /* body of main function */ } 

Si tu fais:

 int main(int argc, char *argv[]) { /* ... */ } 

Ce sont les seuls moyens portables pour définir la fonction main .

Vous devriez probablement avoir un return 0; à la fin, bien que ce ne soit pas ssortingctement nécessaire. Renvoyer 0 indique une exécution réussie. Il existe des moyens d’indiquer que l’exécution a échoué. Je ne vais pas entrer dans cela ici.

Il y a une certaine histoire derrière cela. Les règles pour une définition valide de la fonction main ont changé un peu à travers différentes versions de la norme C.

Avant l’introduction de la première norme officielle pour C en 1989, la forme la plus courante était:

 main() { /* ... */ } 

Ou, si vous souhaitez utiliser des arguments de ligne de commande:

 main(argc, argv) /* argc is implicitly of type int */ char *argv[]; { /* ... */ } 

Il n’y avait aucun moyen de définir une fonction qui ne renvoyait pas de valeur. Si vous n’avez pas spécifié de type de retour, int défaut.

La norme ANSI C de 1989 (qui a été republiée avec des modifications rédactionnelles comme la norme ISO C de 1990) a introduit des prototypes , des déclarations de fonction et des définitions spécifiant les types de parameters. Il existe deux définitions également valables pour main . Vous pouvez utiliser l’un ou l’autre selon que vous devez utiliser des arguments de ligne de commande:

 int main(void) { /* ... */ } 

ou

 int main(int argc, char *argv[]) { /* ... */ } 

( char *argv[] peut également être écrit char **argv . Cette règle ne s’applique qu’aux définitions de paramètre.)

Un compilateur donné peut ou non choisir d’autoriser d’autres formes. Par exemple, certains compilateurs prennent en charge un troisième paramètre, envp .

D’une manière ou d’une autre, certains auteurs ont eu l’idée que void main() ou void main(void) était valide. Il peut être valable pour un compilateur particulier , mais uniquement si ce compilateur le prend explicitement en charge. Ce n’est pas portable. La chose étrange à propos de cela est que la même norme qui a introduit le mot-clé void simultanément établi la règle que le type de retour de main est int .

void main() est utile car il indique que l’auteur du livre que vous lisez ne connaît pas très bien le langage C et que vous devriez en trouver un autre.

L’histoire est différente pour les systèmes “autonomes” (embarqués). Pour de tels systèmes, le point d’entrée du programme est entièrement défini par la mise en œuvre et peut même ne pas être appelé main . Le définir comme void main(void) pourrait bien être valable pour de tels systèmes .

La norme ISO C de 1999 a abandonné la règle “implicit int”. Profiter de cette règle n’était probablement jamais une bonne idée. À partir de l’ISO C 1990, vous pouvez utiliser légalement:

 main(void) { /* ... */ } 

parce que c’était équivalent à:

 int main(void) { /* ... */ } 

À partir de la norme de 1999, l’ int est obligatoire.

La norme de 1999 a également ajouté une règle de cas particulier: atteindre la fermeture de la fonction main équivaut à exécuter le return 0; . Ce n’est toujours pas une mauvaise idée d’append le return 0; explicite return 0; , surtout si votre code peut être compilé avec un compilateur antérieur à C99.

La norme ISO C 2011 n’a apporté aucune modification dans ce domaine.

La différence entre int main() et int main(void) est que ce dernier dit explicitement que main ne prend aucun argument; le premier ne précise pas le nombre d’arguments nécessaires. Utilisez le formulaire int main(void) . Il y a eu des débats pour savoir si int main() est même légal.

Vous pouvez probablement vous en tirer en écrivant void main() , car c’est une erreur que les compilateurs ne sont pas tenus de diagnostiquer (c’est un comportement non défini, à moins que l’implémentation ne le documente).

La ligne de fond: la définition correcte de main a une histoire longue et variée, et il existe de nombreuses variantes que vous pouvez probablement utiliser sans modération. Mais à moins de programmer pour un système embarqué, il est inutile d’utiliser autre chose que l’un des deux formulaires officiellement valides:

 int main(void) { /* ... */ } int main(int argc, char *argv[]) { /* ... */ } 

c implique automatiquement le type de données int à des fonctions sans type de données déclaré. En ce qui concerne le compilateur, voici ce qui suit:

 int main() { printf("hello world\n"); } 

Cela suppose que vous retourniez un entier à la fin de celui-ci avec une instruction return . Si vous le spécifiez explicitement comme void main() vous indiquez au compilateur que la fonction n’a pas de valeur de retour, donc aucun avertissement.

La raison pour laquelle ce n’est pas une erreur est que si non spécifié, main() return 0; en fin d’exécution. Cependant, le compilateur vous avertit toujours que cela se produit.

La meilleure pratique consiste à utiliser int main() , puis à return 0 à la fin de l’exécution de votre programme.

 int main() { printf("hello world\n"); return 0; } 

Voir: cette question pour plus d’informations.

Vous avez reçu l’avertissement, car vous n’avez pas spécifié le type de retour de main .

Vous devez toujours utiliser int main et renvoyer un nombre int , généralement 0 cas de succès.

 int main() { printf("hello world\n"); return 0; //you can omit this since C99 } 

Utiliser void main sur un environnement hébergé (normalement, sinon, ce qui suit ne doit pas nécessairement être vrai) conduit à un comportement indéfini, même si cela fonctionne dans certains compilateurs, ne l’ utilisez jamais .

La norme dit main a deux types de prototype, les deux retours int :

C11 5.1.2.2.1 Démarrage du programme

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

 int main(void) { /* ... */ } 

ou avec deux parameters (appelés ici argc et argv, bien que tous les noms puissent être utilisés, car ils sont locaux à la fonction dans laquelle ils sont déclarés):

 int main(int argc, char *argv[]) { /* ... */ } 

ou équivalent; 10) ou d’une autre manière définie par la mise en oeuvre.

écrire

 return 0 ; 

à la dernière ligne.