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

Langage C++ Discussion :

Link & multiple definition


Sujet :

Langage C++

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 14
    Points : 11
    Points
    11
    Par défaut Link & multiple definition
    Bonjour,

    Ce topic fait suite à celui-ci, mais le problème est a priori indépendant.

    Avec cet ECM :
    Fichier foo.hpp
    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
    21
    22
    23
    24
    25
    26
    27
    28
    #ifndef H_FOO
    #define H_FOO
     
    #include <boost/math/bindings/mpfr.hpp>
    #include <boost/rational.hpp>
     
    namespace std { // std : specialization
      template <> class numeric_limits<mpz_class> {
      public:
        static const bool is_specialized = true;
        static const bool is_signed = false;
      };
    } // namespace std
     
    typedef boost::rational<mpz_class> rat;
     
    class Foo {
    private:
      rat r;
    public:
      Foo() : r() {};
      Foo(const rat& r_) : r(r_) {};
      Foo(const mpz_class& n, const mpz_class& d) : r(n,d) {};
    };
     
    void foo();
     
    #endif // H_FOO
    Fichier foo.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #include <iostream>
    #include "foo.hpp"
     
    void foo() {
      std::cout << "Foo.\n";
      return;
    }
    Fichier try.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include <iostream>
    #include "foo.hpp"
     
    int main(void) {
      mpz_class num("17"), den("29");
      Foo f(num, den);
      foo();
     
      return 0;
    }
    Je compile les fichiers objets sans problème:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ g++ -c foo.cpp
    $ g++ -c try.cpp
    Mais lors de la compilation de l'exécutable :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $ g++ try.o foo.o -lgmp -lmpfr -lgmpfrxx
    foo.o: In function `fmod(__gmp_expr<__mpfr_struct [1], __mpfr_struct [1]> const&, __gmp_expr<__mpfr_struct [1], __mpfr_struct [1]> const&)':
    foo.cpp:(.text+0x0): multiple definition of `fmod(__gmp_expr<__mpfr_struct [1], __mpfr_struct [1]> const&, __gmp_expr<__mpfr_struct [1], __mpfr_struct [1]> const&)'
    try.o:try.cpp:(.text+0x0): first defined here
    foo.o: In function `boost::math::detail::bessel_i0(__gmp_expr<__mpfr_struct [1], __mpfr_struct [1]>)':
    foo.cpp:(.text+0x1cc): multiple definition of `boost::math::detail::bessel_i0(__gmp_expr<__mpfr_struct [1], __mpfr_struct [1]>)'
    try.o:try.cpp:(.text+0x1cc): first defined here
    foo.o: In function `boost::math::detail::bessel_i1(__gmp_expr<__mpfr_struct [1], __mpfr_struct [1]>)':
    foo.cpp:(.text+0xeb1): multiple definition of `boost::math::detail::bessel_i1(__gmp_expr<__mpfr_struct [1], __mpfr_struct [1]>)'
    try.o:try.cpp:(.text+0xeb1): first defined here
    collect2: ld returned 1 exit status
    Mes deux .o contiennent donc des symbols de fonctions identiques (ceux référant aux fonctions bessel et compagnie du binding de gmp/mpfr).
    Comment y remédier ?

    En vous remerciant.

  2. #2
    Membre émérite
    Avatar de skeud
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2011
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Juin 2011
    Messages : 1 091
    Points : 2 724
    Points
    2 724
    Billets dans le blog
    1
    Par défaut
    Tu défini les constructeur de foo, dans le .hpp donc a chaque inclusion de ton fichier, le constructeur est re-défini.

    Pour palier à ce problème (et pour avoir un code plus propre), défini juste le prototype de ton constructeur dans le .hpp et défini-le dans le .cpp.
    cad met le code de ton constructeur dans foo.cpp
    Pas de solution, pas de probleme

    Une réponse utile (ou +1) ->
    Une réponse inutile ou pas d'accord -> et expliquer pourquoi
    Une réponse à votre question


  3. #3
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    @skeud: Normalement non, définir le constructeur d'une classe dans celle-ci dans le header n'est pas un problème. Dans ce cas c'est fonction inline (définie dans la classe), et on peut définir plusieurs fois une fonction inline dans un même programme.

  4. #4
    Membre émérite
    Avatar de skeud
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2011
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Juin 2011
    Messages : 1 091
    Points : 2 724
    Points
    2 724
    Billets dans le blog
    1
    Par défaut
    ah ok on m'as toujours appris a ne mettre que les fonction inline dans un .hpp et c'est tout. Puis des constructeurs en inline, je vois pas trop l'interet
    Pas de solution, pas de probleme

    Une réponse utile (ou +1) ->
    Une réponse inutile ou pas d'accord -> et expliquer pourquoi
    Une réponse à votre question


  5. #5
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Compile avec uniquement l'inclusion des deux .h, et ajoute progressivement du code.

  6. #6
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,
    Dans mpfr.h, au moins les fonctions indiquées par ton compilo (fmod, bessel_i1 et bessel_i0) sont définis sans inline, donc autant de fois que le fichier est inclus. D'où l'erreur de link.

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 14
    Points : 11
    Points
    11
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    Salut,
    Dans mpfr.h, au moins les fonctions indiquées par ton compilo (fmod, bessel_i1 et bessel_i0) sont définis sans inline, donc autant de fois que le fichier est inclus. D'où l'erreur de link.
    J'ai bien compris cela, je le dis à la fin de mon post. J'aimerais savoir comment je peux me débrouiller pour éviter le problème.

  8. #8
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    3 pistes :
    1. relire la doc des différentes bibliothèques pour voir si ton usage est normal ;
    2. décortiquer le doc pour voir si l'absence d'inline est normal ;
    3. supputer une erreur (ça arrive aussi) dans le wrapper boost et rajouter discrètement le mot inline à la définition des fonctions incriminées.
    Piste 3...

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 14
    Points : 11
    Points
    11
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    supputer une erreur (ça arrive aussi) dans le wrapper boost et rajouter discrètement le mot inline à la définition des fonctions incriminées.
    Piste 3...
    In fact : mpfr.hpp (fmod : 5ième fonction : pas de inline)

    (J'ai tendance à faire confiance à des librairies comme celle-ci, mais apparemment le binding n'a pas été fortement testé.)

  10. #10
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,
    Citation Envoyé par Pece_ Voir le message
    In fact : mpfr.hpp (fmod : 5ième fonction : pas de inline)
    C'est ce que je disais dans mon premier message. Ces fonctions ne sont pas définies inline
    Citation Envoyé par Pece_ Voir le message
    (J'ai tendance à faire confiance à des librairies comme celle-ci, mais apparemment le binding n'a pas été fortement testé.)
    Ben, moi aussi. Dans 99,99% des cas, le problème n'est pas du au compilateur/à l'OS/au HW/aux bibliothèques externes/... mais il y a des fois où. Et là, en lisant le header, ça ressemble quand même à un oubli.

  11. #11
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    À voir avec le codeur de la bibliothèque.

    Mais c'est étonnant que ce n'ait pas été levé plus tôt, car apparemment, le code a au moins 9 mois.

  12. #12
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par oodini Voir le message
    Mais c'est étonnant que ce n'ait pas été levé plus tôt, car apparemment, le code a au moins 9 mois.
    De là à dire que cette feature est massivement utilisée...

  13. #13
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 14
    Points : 11
    Points
    11
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    De là à dire que cette feature est massivement utilisée...
    En effet. Si j'ai été confronté à cette erreur, c'est un peu par hasard. J'utilisais des rationnels, et afin que mon algo puisse tourner sur des précisions plus importantes, j'ai voulu avoir un type big int sans modifier le reste de l'algo utilisant la classe Boost::rational. Mais il me semble que la famille GMP/MPFR propose directement des solutions pour manipuler les rationnels à précision arbitraire.

    En tout cas, merci beaucoup de votre aide. Je mets en résolu.

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

Discussions similaires

  1. Multiple definition error (link)
    Par SpongeBob dans le forum Débuter
    Réponses: 7
    Dernier message: 14/08/2008, 18h45
  2. multiple definition of operator<<...
    Par kleenex dans le forum C++
    Réponses: 3
    Dernier message: 05/05/2006, 02h56
  3. [linking de projet] definition multipe
    Par leonardoo dans le forum Autres éditeurs
    Réponses: 13
    Dernier message: 28/01/2006, 20h10
  4. [LG]Interfaces et multiples définitions
    Par fatt dans le forum Langage
    Réponses: 2
    Dernier message: 15/04/2004, 22h41
  5. multiple definition
    Par scorbo dans le forum C
    Réponses: 5
    Dernier message: 10/09/2003, 13h16

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