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 :

Usage pour les #include


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2009
    Messages : 13
    Par défaut Usage pour les #include
    Bonjour,

    supposons que dans un fichier d'en tête j'ai besoin de foo.h et de bar.h
    Mais que bar.h inclut déjà foo.h (donc je peux me contenter d'inclure seulement bar.h).

    Est-ce que j'inclus les deux ou seulement bar.h ?

    Merci.

  2. #2
    Membre chevronné Avatar de Jenna
    Inscrit en
    Décembre 2009
    Messages
    272
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Décembre 2009
    Messages : 272
    Par défaut
    Pour moi, la règle est assez simple :
    • Si tu as besoin d'un composant de bar.h, tu inclus bar.h
    • Si tu as besoin d'un composant de foo.h, tu inclus foo.h


    Si bar.h a besoin d'un composant de foo.h il doit l'inclure. Un include file devrait être complet et ne devrait forcer l'utilisateur à rechercher ce dont à besoin bar.h pour l'inclure avant.

    De toute façon, si foo.h est inclus 2 fois (par ton module et par bar.h inclus par ton module), cela ne doit pas poser de problème non plus.

  3. #3
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Par défaut
    +1 ... J'inclus les fichiers qu'il faut quand il faut. De toute manière, si tu inclus le même fichier dans différents headers ou sources, si c'est bien fait (protection contre les inclusions multiples) y'a aucun problème !
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  4. #4
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    Il y en a pourtant un, de problème : ralentissement pouvant être très sensible de la vitesse de compilation, et pollution assez lourde d'un graphe de dépendance si l'on décide (ou que l'on a l'habitude) d'en utiliser... Ce qui pose d'énormes problèmes d'ailleurs lorsque l'on veut effectuer la séparation d'un module en deux parties, ou simplement analyser les dépendances.

    Pour ma part, c'est plutôt le contraire : je vise à vérifier / m'assurer que l'on n'inclus pas les entêtes de façon inutile et/ou redondante.
    Par contre, je vise également à ce que les entêtes .H soient complets (= ne requièrent pas d'inclusions additionnelles dans un C/CPP qui les utiliseraient) : il est donc hors de question de supprimer une inclusion "comme ça", il faut malgré tout que la chaîne d'inclusion totale soit correcte ET complète.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  5. #5
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 469
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 469
    Par défaut
    Bonjour,

    Citation Envoyé par cirdan_elf Voir le message
    donc je peux me contenter d'inclure seulement bar.h). Est-ce que j'inclus les deux ou seulement bar.h ?
    - Sémantiquement, tu dois inclure le fichier qui définit l'entité que tu utilises ;
    - Techniquement, rien ne garantit la manière dont le fichier inclus sera écrit. D'une plate-forme à l'autre, il se peut très bien que le sous-fichier inclus ne le soit plus. Il faut donc agir comme si tu ne pouvais voir l'intérieur de ce fichier.

    Plus précisément, il n'y a pas de relation hiérarchique entre les *.h comme il y en a dans un arbre de classes objet, par exemple. bar.h « n'implique pas » foo.h. Par ailleurs, la directive #include sert à inclure n'importe quoi, pas forcément des *.h. C'est assez rare de voir autre chose, bien sûr, mais c'est le cas avec les *.xpm, par exemple.

    Pour éviter que le contenu d'un *.h soit redéfini plusieurs fois, on l'encadre généralement avec des macros du genre :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #ifndef FOO_H
    #define FOO_H 1
     
    ... [contenu] ...
     
    #endif

    Il te faudra penser à le faire à ton tour si, toi aussi, tu écris une bibliothèque et fournis son *.h.

    Citation Envoyé par Mac LAK Voir le message
    Pour ma part, c'est plutôt le contraire : je vise à vérifier / m'assurer que l'on n'inclus pas les entêtes de façon inutile et/ou redondante. Par contre, je vise également à ce que les entêtes .H soient complets (= ne requièrent pas d'inclusions additionnelles dans un C/CPP qui les utiliseraient) : il est donc hors de question de supprimer une inclusion "comme ça", il faut malgré tout que la chaîne d'inclusion totale soit correcte ET complète.
    Ce n'est pas sa question : il ne s'agit pas de coller des headers classique pour l'hygiène mais, au contraire, de savoir s'il faut volontairement omettre un header requis parce qu'un autre est réputé l'avoir inclus lui-même auparavant. La réponse est « non », pour les raisons exposées ci-dessus.

    Pour les délais de compilation, aucun overhead notable n'est introduit si le fichier est encadré par les bonnes macros. Son interprétation prend fin dès le départ, lorsque la ligne idoine est atteinte. Pour les graphes des dépendances, celles-ci peuvent former un cycle sans que ce soit forcément une erreur. C'est donc à toi (ou à ton logiciel traceur) de conserver une liste de chaque fichier inclus et d'interrompre la progression de la recherche lorsqu'il est fait référence à un fichier de cette liste.

  6. #6
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Obsidian Voir le message
    Ce n'est pas sa question : il ne s'agit pas de coller des headers classique pour l'hygiène mais, au contraire, de savoir s'il faut volontairement omettre un header requis parce qu'un autre est réputé l'avoir inclus lui-même auparavant. La réponse est « non », pour les raisons exposées ci-dessus.

    Pour les délais de compilation, aucun overhead notable n'est introduit si le fichier est encadré par les bonnes macros. Son interprétation prend fin dès le départ, lorsque la ligne idoine est atteinte. Pour les graphes des dépendances, celles-ci peuvent former un cycle sans que ce soit forcément une erreur. C'est donc à toi (ou à ton logiciel traceur) de conserver une liste de chaque fichier inclus et d'interrompre la progression de la recherche lorsqu'il est fait référence à un fichier de cette liste.

  7. #7
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    Citation Envoyé par Obsidian Voir le message
    Ce n'est pas sa question : il ne s'agit pas de coller des headers classique pour l'hygiène mais, au contraire, de savoir s'il faut volontairement omettre un header requis parce qu'un autre est réputé l'avoir inclus lui-même auparavant. La réponse est « non », pour les raisons exposées ci-dessus.
    Chose pourtant classiquement faite sur pas mal d'entêtes standards et/ou d'OS... Typiquement, si tu développes sous Windows, je pense que tu auras rarement inclus "winbase.h" et que tu inclus directement "windows.h"...

    Pour le "réputé", il y a aussi le fait d'avoir des entêtes complets sans scories (= TOUS les entêtes requis par l'utilisation du .H, et SEULEMENT ces entêtes). Donc, il n'y a pas de "réputé" : si tu utilises un module XX qui manipule des std::string, il est inutile d'inclure toi-même <string> : le header "XX.h" le fait pour toi, s'il est complet. Et tu peux généraliser ça à toute sous-classe, entité ou type manipulé par la classe que tu as utilisée.
    Si par contre tu "profites" d'une inclusion de <string> via un header qui ne manipule pas publiquement de chaînes, là, c'est effectivement mauvais de conserver cette inclusion : il faudrait la supprimer du header qui ne l'utilise pas.

    Citation Envoyé par Obsidian Voir le message
    Pour les délais de compilation, aucun overhead notable n'est introduit si le fichier est encadré par les bonnes macros.
    L'absence de macros peut (et souvent, va) provoquer des warnings au mieux, des erreurs au pire. Pour le reste, le fichier est malgré tout inclus et passé au préproc, même s'il ne génère que des lignes vides. Si c'est juste un .H à toi de 20 lignes, ce n'est pas trop grave. Si c'est "windows.h" et toute sa tripaille que tu inclus N fois pour rien, ça commence à devenir nettement plus sérieux, et plus tu multiplies ce phénomène, plus l'impact est lourd. Pour ma part, je vois nettement le souci sur les inclusions des entêtes ACE, par exemple : en rajouter "pour rien", c'est un ralentissement sensible de la vitesse de compilation... Surtout que si tu exagères un peu trop, tu finis par avoir besoin de swapper. OK, les fichiers peuvent être dans le cache, mais sur une très (trop ?) grosse partie, tu vas te retrouver avec deux processus qui réclament la RAM : le compilateur pour le fichier en cours de compilation, et le cache pour les maintenir disponibles.

    Fais le test avec cet entête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    const int TEST_INCLUDE_START = 0 ;
    #ifndef TEST_INCLUDE
    #define TEST_INCLUDE
     
    // Rajouter N lignes vides et/ou copier ce commentaire
     
    #endif
    const int TEST_INCLUDE_END = 1 ;
    Si tu l'inclus plusieurs fois, tu le verras plusieurs fois définies dans le fichier prétraité (-E), et les numéros de ligne vérifiés (et affichés) à chaque inclusion de cet entête. Suivant le compilateur et les réglages, tu auras ou non les lignes vides maintenues dans le fichier prétraité.

    Citation Envoyé par Obsidian Voir le message
    Pour les graphes des dépendances, celles-ci peuvent former un cycle sans que ce soit forcément une erreur. C'est donc à toi (ou à ton logiciel traceur) de conserver une liste de chaque fichier inclus et d'interrompre la progression de la recherche lorsqu'il est fait référence à un fichier de cette liste.
    En l'occurrence, Doxygen n'effectue pas cette coupe (et heureusement, d'ailleurs, ça permet aussi de résoudre des problèmes de complétude des entêtes). Quant aux dépendances cycliques (ou encore pire : inutiles), c'est de toutes façons quelque chose d'assez crasseux pour laquelle il est quand même souhaitable de se poser la question "ai-je correctement fait ma conception de modules ?"...
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

Discussions similaires

  1. Solution pour les include d'include ?
    Par Nowwis dans le forum Langage
    Réponses: 1
    Dernier message: 01/08/2010, 22h01
  2. Réponses: 8
    Dernier message: 04/04/2009, 12h14
  3. Bouml Preserved Body pour les includes
    Par escafr dans le forum BOUML
    Réponses: 11
    Dernier message: 15/04/2008, 10h47
  4. Réponses: 6
    Dernier message: 28/09/2004, 16h47
  5. Règles pour les #include
    Par julian_ross dans le forum MFC
    Réponses: 2
    Dernier message: 24/02/2004, 09h57

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