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 :

Undefined reference étrange


Sujet :

C++

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2011
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2011
    Messages : 31
    Points : 22
    Points
    22
    Par défaut Undefined reference étrange
    Bien le bonjour,

    J'ai un petit pépin de référence indéfinie.
    J'ai 2 paires de fichiers que j'appellerai D et G (en .h et .cc à chaque fois pour bien séparer les déclarations du reste).

    Le fichier D.h définit une fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    static bool isEqual(const CDart*, const CDart*);
    Les objets CDart sont implémentés ailleurs et fonctionnent très bien. Sans surprise le but de cette fonction est de renvoie vrai si les 2 CDarts que l'on compare (via pointeurs) sont identiques.

    Dans le fichier G.cc j'ai une fonction qui va appeller celle-ci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    bool identique = CDart::isEqual(dartCourante.getBeta1(), bifaceCherchee[it2].getBeta1());
    Les fonctions getBeta1 et 2 renvoient des pointeurs vers des CDart.

    Le message d'erreur obtenu est le suivant :
    undefined reference to `Map2d::CDart::isEqual(Map2d::CDart const*, Map2d::CDart const*)'
    Or je ne comprend pas puisque c'est bel est bien la bonne fonction, avec le bon type de paramètre que l'on utilise. Quelqu'un aurait une idée ?
    Merci d'avance !

  2. #2
    Membre régulier
    Profil pro
    Ingénieur
    Inscrit en
    Avril 2013
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur

    Informations forums :
    Inscription : Avril 2013
    Messages : 77
    Points : 107
    Points
    107
    Par défaut
    Ta fonction est définie dans le header. Plusieurs questions se posent:
    - as tu bien inclus le header dans le cpp?
    - as tu déclaré dans le header, la fonction en tant que membre d'une classe?
    Car pour une classe, une fonction membre statique est une fonction qui ne modifiera pas l'objet; mais hors d'une classe, une fonction statique n'est pas visible de l'extérieur.
    A priori, étant donné ton appel de fonction, ta fonction appartient à la classe statique CDart, donc doit être définie en tant que membre de cette classe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class CDart
    {
        public:
            CDart();
            static bool isEqual(const CDart*, const CDart*);
    };

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2011
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2011
    Messages : 31
    Points : 22
    Points
    22
    Par défaut
    Merci de la réponse rapide.
    Pour répondre à tes questions :
    J'ai bien inclu dans G.cc (resp D.cc) les fichiers G.h (resp D.h).
    J'ai effectivement déclaré la fonction isEqual dans les méthodes publiques de CDart.

    J'ai essayé à tout hasard de faire sauter le 'static' de la définition et de l'implémentation de isEqual en me disant qu'après tout ce n'était pas dramatique si le code ne se rendait pas compte que rien n'était modifié. En faisant ça, j'ai l'erreur suivante :
    erreur: cannot call member function ‘bool Map2d::CDart::isEqual(const Map2d::CDart*, const Map2d::CDart*)’ without object
    J'ai donc abandonné cette voie pour retourner à quelque chose qui me semblait plus normal avec le static.

    je précise également que le fichier G.H inclu bien le fichier D.h et que j'arrive à naviguer dans la fonction isEqual en cliquant directement sur l'appel de fonction grace à mon IDE, ce qui pour moi veux dire que cette fonction était bien trouvée...

  4. #4
    Membre averti
    Profil pro
    professeur des universités à la retraite
    Inscrit en
    Août 2008
    Messages
    364
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : professeur des universités à la retraite

    Informations forums :
    Inscription : Août 2008
    Messages : 364
    Points : 439
    Points
    439
    Par défaut
    Petite parenthèse : donner des noms d'une seule lettre à tes fichiers n'est pas recommandé, mieux vaut donner des noms plus longs ayant un sens de façon à s'y retrouver... toi plus tard ou un autre mainteneur du code.

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2011
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2011
    Messages : 31
    Points : 22
    Points
    22
    Par défaut
    Mes fichiers ont bel et bien des noms plus longs (en l'occurence dart.h et graphGrammar.h) mais je ne voulais pas rentrer trop dans le détail et embrouiller tout le monde. Néanmoins merci du conseil, ça ne fait jamais de mal d'en recevoir !

    Sinon j'ai toujours mon problème :
    undefined reference to 'Map2d::CDart::isEqual(Map2d::CDart const*, Map2d::CDart const*)'
    Quelqu'un aurait une idée ? Pour le prototype de isEqual et ses appels sont pour moi identiques, j'avoue être complètement perdu.

    Merci encore à tout ceux qui cherchent pour m'aider.

  6. #6
    Membre régulier Avatar de GrosLapin
    Homme Profil pro
    Ingénieur et Etudiant
    Inscrit en
    Avril 2013
    Messages
    47
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur et Etudiant

    Informations forums :
    Inscription : Avril 2013
    Messages : 47
    Points : 85
    Points
    85
    Par défaut
    Salut,

    Est ce que tu pourrais mettre les grandes lignes de tes 4 fichiers ?

    Ça serais plus simple pour tenter de reproduire ton erreur

    Ps : Il y a pas de feinte de namespace dans tes fichiers ?

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2011
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2011
    Messages : 31
    Points : 22
    Points
    22
    Par défaut
    Bonjour,
    Voici toutes les parties du code concernées par le problème. J'espère que ça aidera !

    Fichier Darh.hh
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    #ifndef DART_HH
    #define DART_HH
    namespace Map2d
    {
    class CDart
      {
      public:
       [liste fonctions]
       ///Compare 2 brins passés en paramètre. Renvoie vrai s'ils sont identiques.
        static bool isEqual(CDart*, CDart*);
    }
    //fin namespace
    }
     
    #include INCLUDE_INLINE("dart.icc")
    #endif
    Fichier dart.icc
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    namespace Map2d
    {
    [liste de fonctions]
    INLINE
    static bool isEqual(CDart* dart1, CDart* dart2){
        bool equal = true;
        return equal; //Version simplifiée //
    }
    // fin namespace Map2d
    }
    Fichier graphGrammar.hh

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    #ifndef GRAPHGRAMMAR_H
    #define GRAPHGRAMMAR_H
    #include <iostream>
    #include <vector>
    #include <string>
    #include "dart.hh"
     
    using namespace Map2d;
    using namespace std;
     
    class GraphGrammar{
    [contenu de classe]
    };
     
    //Fonction externe à la classe appellant la fonction isEqual de dart.hh
    vector<CDart> engendrerBiface(CDart*);
    #endif
    Fichier graphGrammar.cc

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    #include "graphGrammar.hh"
    #include <vector>
    #include <string>
     
    using namespace std;
     
    vector<CDart> engendrerBiface(CDart* d){
        //Vecteur d'objets de type CDart engendrant ce qu'on appelle une biface
        vector<CDart> biface;
        CDart* dartCourante = d;
     
        //Ajoute des éléments dans le vecteur biface jusqu'à ce qu'on tombe sur 2 darts identiques. La fonction getBeta1() appliqué à une CDart renvoit un pointeur vers un successeur de cette CDart.
        do{
            biface.push_back(*dartCourante);
            dartCourante = dartCourante->getBeta1();
        }while(CDart::isEqual(dartCourante->getBeta1(), d->getBeta1()) == false);
       [traitements fonctionnels]
     
        return biface;
    }
    Je précise que je ne suis pas l'auteur des fichiers dart.hh et dart.icc, je n'ai pas le droit de modifier leur structure/agencement, juste d'y insérer des fonctions (comme je l'ai fait pour "isEqual") contrairement aux fichiers graphGrammar.

    Eventuellement je peux tout chambouler dans graphGrammar.hh et .cc si cela résoud le problème tant que cela ne nuit pas à ce que je veux faire. Typiquement la fonction engendrerBiface par exemple ne peut pas être déplacée dans la class GraphGrammar. En revanche rien ne m'empêche de modifier les prototypes/définitions types etc... tant que j'arrive à comparer deux objets de type CDart.

  8. #8
    Membre régulier Avatar de GrosLapin
    Homme Profil pro
    Ingénieur et Etudiant
    Inscrit en
    Avril 2013
    Messages
    47
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur et Etudiant

    Informations forums :
    Inscription : Avril 2013
    Messages : 47
    Points : 85
    Points
    85
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    namespace Map2d
    {[liste de fonctions]
    INLINE
    static bool isEqual(CDart* dart1, CDart* dart2){
        bool equal = true;
        return equal; //Version simplifiée //
    }
    // fin namespace Map2d
    }
    Test avec ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    namespace Map2d
    {
     
        bool CDart::isEqual(CDart* dart1, CDart* dart2)
        {
            bool equal = true;
            return equal; //Version simplifiée //
        }
    // fin namespace Map2d
    }
    J'avais la même erreur que toi, j'ai rajouté le CDart:: et ça marche. Tu lui ne lui disais pas que tu implémentais la fonction de la classe, il s'y retrouvait pas le pauvre petit

    Dit moi si ça marche chez toi

  9. #9
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 611
    Points
    30 611
    Par défaut
    Salut,

    Et pour que l'explication soit complète:

    Il faut savoir que rien n'empêche une classe d'avoir une fonction membre dont le nom est identique à celui d'une fonction libre.

    Le code suivant est tout à fait valide, compile et s'exécute même tout à fait correctement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include <iostream>
    class MaClasse{
        public:
            void print() {std::cout<<"print() depuis un objet"<<std::endl;}
    };
    void print(){std::cout<<"print() en tant que fonction libre"<<std::endl;}
    int main(){
        print();
        MaClasse obj;
        obj.print();
        return 0;
    }
    Lorsque l'on exécute ce tout petit code, on se rend compte que l'appel de print() effectué à la ligne 8 utilise la définition qui se trouve en ligne 6 et que l'appel effectué à la ligne 10 (obj.print()) exécute la fonction qui est définie en ligne 4.

    La raison en est relativement simple...

    En fait, la signature de la fonction qui est définie en ligne 4 n'est pas void print() mais... void MaClasse::print(). (On parle généralement de "nom pleinement qualifié").

    Dans ce premier code, tu n'aurais pas pu te rendre compte de cette subtilité, parce que la définition de la fonction se trouvait directement dans la définition de la classe.

    Il faut savoir que cette manière de travailler n'est pas sans conséquence, mais tout à fait légale

    Si tu veux "déporter" la définition d'une fonction membre d'une de tes classe, il faut que tu définisse la fonction selon son nom pleinement qualifié, ce qui donnerait quelque chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    #include <iostream>
    class MaClasse{
        public:
            void print();
    };
    void print();
    int main(){
        print();
        MaClasse obj;
        obj.print();
        return 0;
    }
    /* ca, c'est la définition de la fonction libre */
    void print(){std::cout<<"print() en tant que fonction libre"<<std::endl;}
    /* et ca, la définition de la fonction membre de MaClasse */
    void MaClasse::print() {std::cout<<"print() depuis un objet"<<std::endl;}
    Ceci étant dit, isEqual pourrait très bien être une fonction libre plutôt qu'une fonction membre statique.

    En effet, tu donnes donnes une responsabilité à ta classe CDart qu'elle n'a, a priori, aucune raison d'avoir : celle de vérifier que deux pointeurs de type CDart soit identiques (quelle que soit le sens que l'on puisse donner à isEqual).

    De plus, cela t'oblige à utiliser le nom pleinement qualifié de la fonction lorsque tu l'appelle ( sous la forme de if(CDart::isEqual(ptr1,ptr2)) ) alors qu'il est tout à fait possible d'avoir plusieurs version de isEqual prenant chacune des pointeurs sur des type différents sans que cela ne vienne à poser problème.

    Pour rappel, C++ est un langage multiparadigme, et le premier paradigme qu'il autorise est le paradigme "impératif": nous ne sommes pas en java ou en C# qui obligent toutes les fonctions à être des fonctions membres d'une classe, y compris la fonction principale (main() )
    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

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2011
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2011
    Messages : 31
    Points : 22
    Points
    22
    Par défaut
    Tout d'abord, merci pour vos réponses ! Ca n'a pas encore totalement résolut mon problème mais j'ai bien avancé !

    GrosLapin effectivement vu la façon dont je l'avais implémenté, il fallait effectivement que je rajoute un "CDart::" devant le nom de la fonction.
    Quand j'ai fait ça, j'ai constaté une nouvelle erreur pour me signaler que je ne pouvais pas appeller CDart::isEqual... sans objet CDart ! Et là je me suis tapé violemment sur la tête.

    Comme tu l'as dit koala01, il n'y a, a priori AUCUNE raison pour que isEqual soit membre de CDart, au contraire il ne le faut PAS puisque je vais devoir appeller cette méthode non pas depuis un objet CDart, mais sur 2 pointeurs. Par conséquent j'ai "sorti" isEqual de la classe CDart et opéré des modifications dans le code pour en tenir compte.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    #ifndef DART_HH
    #define DART_HH
    namespace Map2d
    {
    class CDart
      {
        public:[liste fonctions]
      };
     
       ///Fonction isEqual sortie de la classe
       bool isEqual(CDart*, CDart*);
    }
    //fin namespace
     
    #include INCLUDE_INLINE("dart.icc")
    #endif
    Fichier dart.icc

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    namespace Map2d
    {[liste de fonctions]
    bool isEqual(CDart* dart1, CDart* dart2){ //ici j'ai enlevé le "static"
        bool equal = true;
        return equal; //Version simplifiée //
    }
    // fin namespace Map2d
    }
    Fichier graphGrammar.hh

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    #ifndef GRAPHGRAMMAR_H
    #define GRAPHGRAMMAR_H
    #include <iostream>
    #include <vector>
    #include <string>
    #include "dart.hh"
     
    using namespace Map2d;
    using namespace std;
     
    class GraphGrammar{
    [contenu de classe]
    };
     
    //Fonction externe à la classe appellant la fonction isEqual de dart.hh
    vector<CDart> engendrerBiface(CDart*);
    #endif
    Fichier graphGrammar.cc

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    #include "graphGrammar.hh"
    #include <vector>
    #include <string>
     
    using namespace std;
     
    vector<CDart> engendrerBiface(CDart* d){
        //Vecteur d'objets de type CDart engendrant ce qu'on appelle une biface
        vector<CDart> biface;
        CDart* dartCourante = d;
     
        //Ajoute des éléments dans le vecteur biface jusqu'à ce qu'on tombe sur 2 darts identiques. La fonction getBeta1() appliqué à une CDart renvoit un pointeur vers un successeur de cette CDart.
        do{
            biface.push_back(*dartCourante);
            dartCourante = dartCourante->getBeta1();
        }while(isEqual(dartCourante->getBeta1(), d->getBeta1()) == false); //ici j'ai viré le "CDart::"
     
        return biface;
    }
    L'ennui maintenant, c'est que j'ai droit à une joli erreur de multiple définition :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    In function `Map2d::isEqual(Map2d::CDart*, Map2d::CDart*)':
    nomFichier.cc:(.text+0x0): multiple definition of `Map2d::isEqual(Map2d::CDart*, Map2d::CDart*)'
    Et le tout pour une quinzaine de fichiers. Ce que je ne comprend pas étant donné que la fonction isEqual est bien définie à l'intérieur d'un bloc #ifndef DART_HH ... #endif.
    Je sais qu'on s'éloigne du sujet de base mais je ne dirai pas non à un coup de pouce...

    En tout cas merci pour l'aide déjà apportée, c'était vraiment tout bête mais ça m'a bien aidé !

  11. #11
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 113
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 113
    Points : 32 958
    Points
    32 958
    Billets dans le blog
    4
    Par défaut
    Pourquoi inclure le .icc et pas le compiler comme .cpp ?
    Il n'y a pas de code template là.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  12. #12
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 611
    Points
    30 611
    Par défaut
    Citation Envoyé par fred94190 Voir le message
    Tout d'abord, merci pour vos réponses ! Ca n'a pas encore totalement résolut mon problème mais j'ai bien avancé !

    GrosLapin effectivement vu la façon dont je l'avais implémenté, il fallait effectivement que je rajoute un "CDart::" devant le nom de la fonction.
    Quand j'ai fait ça, j'ai constaté une nouvelle erreur pour me signaler que je ne pouvais pas appeller CDart::isEqual... sans objet CDart ! Et là je me suis tapé violemment sur la tête.

    Comme tu l'as dit koala01, il n'y a, a priori AUCUNE raison pour que isEqual soit membre de CDart, au contraire il ne le faut PAS puisque je vais devoir appeller cette méthode non pas depuis un objet CDart, mais sur 2 pointeurs. Par conséquent j'ai "sorti" isEqual de la classe CDart et opéré des modifications dans le code pour en tenir compte.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    #ifndef DART_HH
    #define DART_HH
    namespace Map2d
    {
    class CDart
      {
        public:[liste fonctions]
      };
     
       ///Fonction isEqual sortie de la classe
       bool isEqual(CDart*, CDart*);
    }
    //fin namespace
     
    #include INCLUDE_INLINE("dart.icc")
    #endif
    Aaaarggggghhhh!!!!

    On n'inclue JAMAIS un fichier d'implémentation dans un fichier d'en-tête!!!

    Vire moi (et en quatrième vitesse, en plus) ce
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    #include INCLUDE_INLINE("dart.icc")
    que je ne saurais voir (en plus de ne ressembler à rien) !!!

    [EDIT]
    Comme tu l'as dit koala01, il n'y a, a priori AUCUNE raison pour que isEqual soit membre de CDart, au contraire il ne le faut PAS puisque je vais devoir appeller cette méthode non pas depuis un objet CDart, mais sur 2 pointeurs. Par conséquent j'ai "sorti" isEqual de la classe CDart et opéré des modifications dans le code pour en tenir compte.
    Ceci dit, tu aurais pu en faire une fonction statique de ta classe CDart (en l'implémentant avec son nom pleinement qualifié ), l'aurait rendue indépendante de tout objet de type CDart et t'aurait permis un code proche de CDart::isEqual(ptr1,ptr2), mais je ne crois vraiment pas que ce soit judicieux pour cette fonction particulière [/EDIT]
    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

  13. #13
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2011
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2011
    Messages : 31
    Points : 22
    Points
    22
    Par défaut
    Ah ! Le coté rassurant c'est qu'il n'y a pas que moi que cet include choquait...
    Comme je l'ai dit plus haut ce fichier fait parti d'un code que l'on m'a généreusement soumis pour me faire gagner du temps en développant quelque chose de fortement lié, ce n'est donc pas moi qui ait implémenté cette partie.

    Le fichier dart.cc contenait uniquement un petit bloc
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #include "inline-macro.hh"
    #include INCLUDE_HEADER("dart.hh")
    #include INCLUDE_NON_INLINE("dart.icc")
    Le principe de ce qu'a voulut faire la personne parait clair, mais effectivement ce n'est pas comme cela qu'il aurait du procéder !

    J'ai de ce pas viré le fichier icc, mis son contenu dans le .cc et modifé les includes en conséquence, viré les INLINE,... et tout marche !

    Je ne comprend pas pourquoi cette partie à été faite comme cela, pour moi ça n'avait pas de sens mais je n'allais pas m'amuser à changer l'architecture de quelque chose qui marchait de base. Devant vos réactions indignésje suis passé outre le "touche pas à mon code". J'en discuterai avec l'autre développeur pour voir s'il avait une raison, mais en attendant, tout marche au poil comme ça, et c'est bien plus propre !

    Sujet clôs, merci encore pour votre aide !

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Aaaarggggghhhh!!!!

    On n'inclue JAMAIS un fichier d'implémentation dans un fichier d'en-tête!!!

    Vire moi (et en quatrième vitesse, en plus) ce
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    #include INCLUDE_INLINE("dart.icc")
    que je ne saurais voir (en plus de ne ressembler à rien) !!!
    Pour le cas des fonctions inline, qui doivent être utilisées en inclusion de toute façon, j'ai du mal à voir le problème (tant qu'il n'y a pas d'histoires de références croisées dans ledit fichier d'implémentation). Des #include "xxxx.inl", il y en a partout dans les headers MFC.
    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.

  15. #15
    Membre régulier Avatar de GrosLapin
    Homme Profil pro
    Ingénieur et Etudiant
    Inscrit en
    Avril 2013
    Messages
    47
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur et Etudiant

    Informations forums :
    Inscription : Avril 2013
    Messages : 47
    Points : 85
    Points
    85
    Par défaut
    Ce que je ne comprend pas étant donné que la fonction isEqual est bien définie à l'intérieur d'un bloc #ifndef DART_HH ... #endif.
    J’avoue que j'ai du mal a comprendre également.

    Cela permet d'éviter que le texte soit inclus plusieurs fois, à la suite de plusieurs appels de #include. En effet, au premier appel, DejaLa n'est pas connu du préprocesseur. Il est donc déclaré et le texte est inclus. Lors de tout autre appel ultérieur, DejaLa existe, et le texte n'est pas inclus. Ce genre d'écriture se rencontre dans les fichiers d'en-tête, pour lesquels en général on ne veut pas qu'une inclusion multiple ait lieu.
    D'après : Cours de C/C++, Le préprocesseur

  16. #16
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 611
    Points
    30 611
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Pour le cas des fonctions inline, qui doivent être utilisées en inclusion de toute façon, j'ai du mal à voir le problème (tant qu'il n'y a pas d'histoires de références croisées dans ledit fichier d'implémentation). Des #include "xxxx.inl", il y en a partout dans les headers MFC.
    J'aurais en effet du préciser "sauf pour les fonctions inline ou template", mais ce sont des cas spécifiques
    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

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Citation Envoyé par koala01 Voir le message
    J'aurais en effet du préciser "sauf pour les fonctions inline ou template", mais ce sont des cas spécifiques
    Le code inclus avait l'extension .icc au lieu de .cc, j'ai donc pensé que ce que tu disais s'appliquait surtout à l'inline...

    vAh, tu as raison.
    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.

  18. #18
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 611
    Points
    30 611
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Le code inclus avait l'extension .icc au lieu de .cc, j'ai donc pensé que ce que tu disais s'appliquait surtout à l'inline...
    C'est surtout que la fonction n'était pas déclarée inline, malgré l'extension
    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

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. winsock.h : undefined reference...
    Par abraxas dans le forum Dev-C++
    Réponses: 14
    Dernier message: 06/08/2012, 14h42
  2. Undefined reference compilation réseau
    Par Ren97 dans le forum Dev-C++
    Réponses: 11
    Dernier message: 08/03/2005, 10h46
  3. Compilation de xmms : undefined reference to...
    Par Michaël dans le forum Applications et environnements graphiques
    Réponses: 4
    Dernier message: 04/02/2005, 20h05
  4. undefined reference to `xmlParseFile'
    Par Clemaster dans le forum Autres éditeurs
    Réponses: 2
    Dernier message: 25/06/2004, 21h38
  5. g++ : undefined reference to ...
    Par le_barbu dans le forum Autres éditeurs
    Réponses: 16
    Dernier message: 14/05/2004, 08h23

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