IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

La fonction main()


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Expert confirmé
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Par défaut La fonction main()
    Bon suite à quelques remarques sur mes tutoriels, j'ai décidé d'ouvrir ce thread afin qu'on puisse discuter un peu de la fonction main et du coup des fonctions en C en général.

    On est bien d'accord que le prototype de main() est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    > int main(void)
    > ou :
    > int main(int argc, char * argv[])
    Mais comme dans un programme on a rarement besoin d'appeler cette fonction nous-mêmes, il n'est pas nécessaire de la déclarer. Si on devait la déclarer, on écrirait ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    > int main(void);
    > ou :
    > int main(int argc, char * argv[]);
    Selon la forme utilisée.

    Si main() n'est pas appelée dans le programme, on peut se contenter de la définir tout simplement. En particulier, pour la première forme, on peut donc écrire ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int main(void)
    {
        return 0;
    }
    Qui est strictement équivalent (en C90) à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int main()
    {
        return 0;
    }
    Cette forme est toujours acceptée en C99, et même les exemples de n1256 utilisent cette forme.

    Corrigez moi si j'ai tort (point de vue norme uniquement, pas de "je préfère ceci" s'il vous plaît. Moi je préfère l'autre ! Merci).

  2. #2
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    J'avais utilisé dans le temps une autre définition de main qui était
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    int main(int argc, char * argv[], char *envp[])
    dans lequel envp[] pointait sur les variables d'environnement.

    Cette forme de déclaration est complètement obsolète ou bien elle peut encore être utilisée ?
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  3. #3
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Citation Envoyé par ram_0000 Voir le message
    Cette forme de déclaration est complètement obsolète ou bien elle peut encore être utilisée ?
    C'est une extension au standard, disponible sur les plateformes Unixoides. Non portable, evidemment.

  4. #4
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Les deux formes sont équivalentes, mais pas strictement. Dans les deux cas, on définit une fonction main() renvoyant un int et ne prenant aucun paramètre. Par ailleurs, la première forme déclare main sous forme de prototype, ce qui n'est pas le cas de la deuxième. Pour main(), comme tu l'as fait remarquer, ce n'est pas important car elle n'est jamais appelée explicitement dans le programme. En revanche, pour les autres fonctions, il est fortement recommandé de les déclarer sous forme de prototype. Or, pour s'en assurer, gcc offre l'option de compilation -Wstrict-prototypes qui active un avertissement lorsqu'une fonction non déclarée sous forme de prototype est rencontrée. Or, du point de vue de gcc, main() est une fonction comme les autres. Je préfère donc spécifier explicitement que main() ne prend aucun argument. Ceci m'évite d'avoir à trainer un avertissement, même si le code est parfaitement valide sans cela.

    C++ a résolu le problème à la base en rendant ces deux formes de définition de main() strictement équivalentes. Pour ce qui est du C, il y a une asymétrie embêtante entre déclaration faisant partie d'une définition (selon les termes utilisés par la norme) et déclaration ne faisant pas partie d'une définition.

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  5. #5
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Citation Envoyé par Thierry Chappuis Voir le message
    Pour main(), comme tu l'as fait remarquer, ce n'est pas important car elle n'est jamais appelée explicitement dans le programme.
    Il ne faut jamais dire jamais !

  6. #6
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par ram_0000 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int main(int argc, char * argv[], char *envp[])
    Cette forme de déclaration est complètement obsolète ou bien elle peut encore être utilisée ?
    Elle n'a jamais fait partie de la définition du C (K&R ou ANSI). C'est une extension supportée par certains compilateurs sous certains sytèmes...

  7. #7
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Il y a un truc bizarre dans l'évangile selon Visual 6 :
    This argument is ANSI compatible in C, but not in C++
    Notez que la version 2005 ne dit rien de tel.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #8
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Il y a un truc bizarre dans l'évangile selon Visual 6 :

    Notez que la version 2005 ne dit rien de tel.
    c'est louche d'autant que cette section est clairement encadrée par "Microsoft Specific —>"

  9. #9
    Membre chevronné Avatar de dapounet
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2007
    Messages
    469
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2007
    Messages : 469
    Par défaut
    La norme en parle dans les extensions de l'annexe J.5, faut peut-être pas chercher plus loin.

  10. #10
    Expert confirmé
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Par défaut
    Même pas dans les annexes :
    Citation Envoyé par n1256
    5.1.2.2.1 Program startup

    1 The function called at program startup is named main. The implementation declares no prototype for this function. It shall be defined with a return type of int and with no parameters :

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

    or with two parameters (referred to here as argc and argv, though any names may be used, as they are local to the function in which they are declared) :

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

    or equivalent; 9) or in some other implementation-defined manner.
    D'autres proptotypes de main autres que int main(void) et int main(int argc, char * argv[]) sont donc également autorisés mais ils ne sont bien évidemment pas standards.

    Citation Envoyé par Thierry Chappuis
    Citation Envoyé par C89
    An empty list in a function declarator that is part of a function definition specifies that the function has no parameters. The empty list in a function declarator that is not part of a function definition specifies that no information about the number or types of the parameters is supplied.
    Idem en C99.
    10 / 10.

    Donc : Dans la définition d'une fonction qui ne prend aucun argument, void placé entre les parenthèses est complètement facultatif. Dans sa déclaration, qui est une chose à part (définition et déclaration n'apparaissent pas forcément dans le même fichier source ...), il est cependant obligatoire (si on veut indiquer au compilateur que la fonction ne prend aucun argument).

    Merci à tous.

  11. #11
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 741
    Par défaut
    Si nous faisons abstraction du cas de main, pour une fonction, les déclarations

    int foo(void) { ...; }
    int foo() { ...; }


    ne sont pas strictement équivalentes.

    Dans le premier cas, nous disons que la fonction foo n'a pas d'argument et le compilo va raler lorsqu'il rencontrera foo(1).
    Dans le second, pour des raisons de compatibilités, il va accepter une liste quelconque de paramètres.

    Dans le cas de main, cela ne va pas changer grand chose puisque "son prototype" ne sera jamais utilisé. Les implications sont a rechercher dans le "non-fonctionnel" (maintenabilité, lisibilité,...).

    En gros, c'est une question de "style". Elle tourne autour de l'intérêt à être "plus précis" et s'imposer une discipline dans la cohérence de son écriture allant (souvent) au delà du nécessaire (côté fonctionnel).

    Sans vouloir entrer dans ce débat, je pense que si on fait un tuto, il sera préférable d'utiliser int main(void)...
    Si on fait un exemple vite fait pour illustrer ses propos dans une réponse du forum, on pourra être plus laxiste.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  12. #12
    Membre émérite
    Avatar de maxim_um
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    895
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 895
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Si nous faisons abstraction du cas de main, pour une fonction, les déclarations

    int foo(void) { ...; }
    int foo() { ...; }


    ne sont pas strictement équivalentes.

    Dans le premier cas, nous disons que la fonction foo n'a pas d'argument et le compilo va raler lorsqu'il rencontrera foo(1).
    Dans le second, pour des raisons de compatibilités, il va accepter une liste quelconque de paramètres.

    Dans le cas de main, cela ne va pas changer grand chose puisque "son prototype" ne sera jamais utilisé. Les implications sont a rechercher dans le "non-fonctionnel" (maintenabilité, lisibilité,...).

    En gros, c'est une question de "style". Elle tourne autour de l'intérêt à être "plus précis" et s'imposer une discipline dans la cohérence de son écriture allant (souvent) au delà du nécessaire (côté fonctionnel).

    Sans vouloir entrer dans ce débat, je pense que si on fait un tuto, il sera préférable d'utiliser int main(void)...
    Si on fait un exemple vite fait pour illustrer ses propos dans une réponse du forum, on pourra être plus laxiste.

    - W
    Je partage aussi cet avis. Le langage C semble plus permissif que C++, et le fait d'adopter une attitude rigoureuse est la meilleure solution, ne serait-ce que pour des raisons de rétro compatibilité.

    Par ailleurs, la forme

    contrairement à

    ne vas à l'encontre d'aucune des normes du C, alors autant ne pas s'en priver.

  13. #13
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Citation Envoyé par maxim_um Voir le message
    Par ailleurs, la forme

    contrairement à

    ne vas à l'encontre d'aucune des normes du C, alors autant ne pas s'en priver.
    La deuxième forme est valide également. Voir posts plus haut.

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  14. #14
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    Citation Envoyé par Thierry Chappuis Voir le message
    La deuxième forme est valide également. Voir posts plus haut.

    Thierry
    Valide mais peut potentiellement entraîner un comportement indéterminé comme je l'ai expliqué plus haut donc si on parle de bonne pratique de programmation, elle est à éviter!!!

  15. #15
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Citation Envoyé par nicolas.sitbon Voir le message
    Valide mais peut potentiellement entraîner un comportement indéterminé comme je l'ai expliqué plus haut donc si on parle de bonne pratique de programmation, elle est à éviter!!!
    Je n'ai pas dit qu'elle était conseillée, j'ai dit qu'elle était valide.
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  16. #16
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Citation Envoyé par Melem Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int main(void)
    {
        return 0;
    }
    Qui est strictement équivalent (en C90) à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int main()
    {
        return 0;
    }
    Je ne suis pas convaincu que ce soit deux ecritures equivalentes. La premiere (int main(void)) est un prototype, alors que la seconde ne donne que le type de retour.

  17. #17
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    Citation Envoyé par DaZumba Voir le message
    Je ne suis pas convaincu que ce soit deux ecritures equivalentes. La premiere (int main(void)) est un prototype, alors que la seconde ne donne que le type de retour.
    Du point de vue de l'appelé (en l'occurrence main ici), elles sont identiques.
    En revanche du point de vue de l'appelant, il y a une différence qui selon moi justifie de ne jamais utiliser la seconde : si on met explicitement void, comme dit plus, il n'est pas possible d'appeler main ainsi : main(1) car on viole une contrainte. Si au contraire, on laisse les parenthèses vides (), le fait d'appeler main ainsi main(1) ne viole aucune contrainte mais induit un comportement indéterminé.
    En conclusion, afin d'éviter tout comportement indéterminé, la forme main() ne doit pas être utiliser (que ce soit pour main ou tout autre fonction ne recevant pas d'argument).
    J.2 Undefined behavior
    1 The behavior is undefined in the following circumstances:
    ...
    — For a call to a function without a function prototype in scope, the number of
    arguments does not equal the number of parameters (6.5.2.2).

  18. #18
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Citation Envoyé par DaZumba Voir le message
    Je ne suis pas convaincu que ce soit deux ecritures equivalentes. La premiere (int main(void)) est un prototype, alors que la seconde ne donne que le type de retour.
    La seconde ne donne pas seulement le type de retour. Selon la norme, elle spécifie bel et bien que la fonction ne prend aucun argument. Cette forme n'est toutefois pas considérée comme prototype.

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  19. #19
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Citation Envoyé par Thierry Chappuis Voir le message
    Selon la norme, elle spécifie bel et bien que la fonction ne prend aucun argument.
    Ce ne serait pas un ajout C99 par hasard?

  20. #20
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Citation Envoyé par DaZumba Voir le message
    Ce ne serait pas un ajout C99 par hasard?
    Le draft de C89 disponible ici dit:

    Citation Envoyé par C89
    An empty list in a function declarator that is part of a function definition specifies that the function has no parameters. The empty list in a function declarator that is not part of a function definition specifies that no information about the number or types of the parameters is supplied.
    Idem en C99.

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 21
    Dernier message: 20/06/2006, 16h49
  2. fonction main en C++
    Par steph_nied dans le forum C++
    Réponses: 3
    Dernier message: 26/05/2006, 15h03
  3. arguments dans ma fonction main
    Par salseropom dans le forum C
    Réponses: 10
    Dernier message: 15/03/2006, 23h12
  4. la fonction main
    Par harvouj dans le forum Langage
    Réponses: 1
    Dernier message: 13/02/2006, 01h34

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo