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 :

Nécessité des headers


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Avril 2009
    Messages
    45
    Détails du profil
    Informations forums :
    Inscription : Avril 2009
    Messages : 45
    Par défaut Nécessité des headers
    Bonjour à tous,

    je suis complètement novice en C, pas en prog puisque je connais un peu l'ADA, le fortran et le VBA.
    J'ai décidé de me mettre à ce "standard"...

    J'ai lu pas mal de tuto et aucun n'explique clairement la necessité de déclarer les prototypes de fonction dans des headers. Ces mêmes tutos exprime plutot ca comme un choix et non une obligation.

    Ceci se verifie plus ou moins dans ce premier bout de code "simpliste":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    #include <stdio.h>
     
    int main(void)
    {
    test(19);
    }
    int test(int entree)
    {
    printf("test:: %d \n",entree);
    }
    la fonction test ne renvoit pas un int, je suis d'accord mais notez que la compilation ne retourne aucune erreur.

    Par contre, une code comme celui la:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
             #include <stdio.h>
     
        int main()
             {
                 test();
                 return 0;
            }
     
             void test()
            {
                printf("prout");
            }
    retourne une erreur:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Scripts_C/test_2.c:18: warning: conflicting types for ‘test’
    Scripts_C/test_2.c:10: warning: previous implicit declaration of ‘test’ was here

    Qu'en pensez vous?

    Merci

  2. #2
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Bonsoir et bienvenue sur les forums de DVP

    Dans les temps ancestraux, lorsque le langage C et les programmeurs en ce langage en étaient à leurs premiers balbutiements, seule la connaissance du type de retour d'une fonction était (je ne sais pas si c'est une généralité absolue) nécessaire au compilateur pour faire son travail, pas le nombre ni la nature des arguments.
    Si le compilateur ne le connaissait pas, il supposait à tort ou à raison, que le type de retour était int (d'où ce que tu as constaté).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int main(void)
    {
    test(19); // suppose que test retourne int
    }
    int test(int entree) // et c'est vrai
    {
    printf("test:: %d \n",entree);
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
        int main()
             {
                 test(); //suppose que test retourne int
                 return 0;
            }
     
             void test() // mais c'est faux
            {
                printf("prout");
            }
    Depuis ces temps héroïques, la mentalité a changé : Pour la sécurité des programmes, le programmeur ne veut (et ne doit) plus se reposer sur ces comportements par défaut (qui peuvent masquer une erreur), même si, du fait de l'histoire, ils ne sont signalés par le compilateur que comme des avertissements, pas comme des erreurs.
    De plus, on exige maintenant d'un programmeur le prototype complet qui permet au compilateur de faire des vérifications sur la cohérence du programme (ce n'est pas une obligation du langage, mais une obligation que doit s'imposer un programmeur ; il doit la considérer comme un impératif, pas comme un choix)
    Le temps où on pouvait écrire n'importe quoi avec ce langage en abusant de ses aspects permissifs est révolu au bénéfice de la sécurité du code.

  3. #3
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut, et bienvenue sur le forum.

    Il existe généralement deux grand moteurs qui poussent les langages de programmation à évoluer:
    • les problèmes rencontrés "à l'usage" du langage de programmation étudié, comme des comportements par défauts inopportuns voire, l'apparition de cas qui n'avaient pas été envisagés au moment de la création du langage ou de la mise au point de la norme en vigueur
    • L'évolution des techniques de conception et de réalisation

    Le deuxième point tend à essayer de rendre l'exécution des programmes de plus en plus sécurisante et à préférer ce qui est explicitement exprimé à ce qui est implicite.

    De ce point de vue, il faut avouer que, ainsi que l'a fait valoir diogene, le comportement qui consiste à considérer qu'une fonction renvoie automatiquement un entier si le compilateur n'en a pas croisé la déclaration est loin d'apporter la "sécurité optimale"...

    Le fait de déclarer les différentes fonctions avant de les invoquer est l'un des axes permettant d'améliorer la sécurité générale de ton code, et, partant, d'en améliorer la qualité, tout en ne demandant, finalement, qu'un travail supplémentaire assez restreint

    Le fait est que, lorsque tu as un "micro projet" à créer, comme le simple fait de créer une application qui ne nécessite qu'un nombre très limité (si tu y tiens, plaçons la barre à quatre ou cinq, de manière tout à fait arbitraire) de fonctions en plus de la fonction principale (main), il n'y a *sensiblement* pas besoin de réfléchir à "modulariser" ton code: tu peux aisément envisager de tout placer dans un fichier unique (tel que main.c)...

    Par contre, dés que tu envisage un projet plus important, il devient rapidement indispensable de réfléchir à la manière la plus cohérente de "modulariser" ton code, ne serait-ce que parce qu'il est beaucoup plus facile de s'y retrouver dans dix mix de deux cents lignes implémentant chacun une dixaine de fonctions que dans un seul module de deux milles lignes implémentant une centaine de fonctions...(chiffres cités arbitrairement )

    Par contre, cela présente un inconvénient "de taille" si tu accepte comme correct le fait qu'il faille déclarer les fonctions avant d'essayer de les invoquer: certains modules subiront inévitablement une série de dépendances avec certains autres modules particulier.

    Et il faut l'avouer: il deviendrait rapidement ingérable de devoir re-déclarer ces fonctions qui sont définies dans d'autres modules mais que tu désire utiliser : entre les erreurs de copie, les fautes d'orthographe et les doutes concernant le nombre et / ou le type des arguments, il y aurait largement de quoi "virer casaque"...

    Bien sur, ce qui est vrai en ce qui concerne les fonctions l'est en ce qui concerne les structures, les variables globales (même si "c'est mal") et, en gros, tout ce qui peut si volontiers prendre place dans un fichier d'en-tête...

    Le C a toujours eu pour philosophie de laisser "un maximum de libertés" à la personne qui écrit son code (dans les limites de ce que le langage accepte, du moins)...

    C'est pourquoi l'utilisation de fichier(s) d'en-tête n'est pas "obligatoire", mais tu auras surement compris que leur utilisation est de nature, non seulement, à te simplifier énormément la vie, mais, aussi, à t'apporter une sécurité accrue...

    Le C te laisse donc seul juge quant à l'évaluation de l'utilité de cette possibilité qui t'est offerte de recourir aux fichiers d'en-tête, mais, dans bien des cas, cette évaluation devrait t'inciter à les utiliser

    Si la plupart des tutos attendent très longtemps avant d'en parler, c'est "simplement" parce que, quand tu présente un code exemple qui n'utilise qu'un type défini par l'utilisateur et deux ou trois fonctions en plus de la fonction principale, leur utilisation représenterait une "complexité" supplémentaire inutile dans le cadre du concept abordé au point particulier abordé... ni plus, ni moins
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  4. #4
    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 FabTheGeek Voir le message
    Bonjour à tous,

    je suis complètement novice en C, pas en prog puisque je connais un peu l'ADA, le fortran et le VBA.
    J'ai décidé de me mettre à ce "standard"...

    J'ai lu pas mal de tuto et aucun n'explique clairement la necessité de déclarer les prototypes de fonction dans des headers. Ces mêmes tutos exprime plutot ca comme un choix et non une obligation.

    Ceci se verifie plus ou moins dans ce premier bout de code "simpliste":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    #include <stdio.h>
     
    int main(void)
    {
    test(19);
    }
    int test(int entree)
    {
    printf("test:: %d \n",entree);
    }
    la fonction test ne renvoit pas un int, je suis d'accord mais notez que la compilation ne retourne aucune erreur.
    C'est parce que ton compilateur est mal réglé :

    http://emmanuel-delahaye.developpez....-codage-c/#LVI
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
     
    -------------- Build: Debug in hello ---------------
     
    Compiling: main.c
    Linking console executable: bin\Debug\hello.exe
    C:\dev\hello\main.c: In function `main':
    C:\dev\hello\main.c:5: warning: implicit declaration of function `test'
    C:\dev\hello\main.c:6: warning: control reaches end of non-void function
    C:\dev\hello\main.c: In function `test':
    C:\dev\hello\main.c:10: warning: control reaches end of non-void function
    Output size is 18.56 KB
    Process terminated with status 0 (0 minutes, 4 seconds)
    0 errors, 3 warnings
    Il faut utiliser les prototypes.

    http://emmanuel-delahaye.developpez....page=Page3#LXI
    http://emmanuel-delahaye.developpez....ques-codage-c/

    A lire intégralement

Discussions similaires

  1. Réponses: 10
    Dernier message: 16/11/2005, 18h48
  2. [Sécurité] Liste des Header(application)
    Par Anduriel dans le forum Langage
    Réponses: 5
    Dernier message: 06/11/2005, 18h06
  3. [Débutant] Envoyer des header
    Par joseph_p dans le forum Servlets/JSP
    Réponses: 9
    Dernier message: 20/09/2005, 16h42
  4. [IDE] Gestion automatique des headers d'unités
    Par Clorish dans le forum Outils
    Réponses: 1
    Dernier message: 27/06/2005, 18h52
  5. Gestion des headers dans un Makefile
    Par Weren dans le forum Autres éditeurs
    Réponses: 1
    Dernier message: 09/11/2004, 10h44

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