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

Contribuez C++ Discussion :

Template et spécialisation template et optimisation de compilation (-O3) (clang)


Sujet :

Contribuez C++

  1. #1
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    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 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut Template et spécialisation template et optimisation de compilation (-O3) (clang)
    Salut,

    je voulais vous faire part d'une "étrangeté" rencontrée il y a peu.

    Le titre pose le contexte, il s'agit de compiler, sous clang dans mon cas, une fonction template, et surtout une spécialisation template de cette fonction.
    Voyons le cas simplifié, avec une mise en évidence sur un simple cout:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    // MyClass.hpp
    class MyClass {
    public:
      template<class T> void Send(const T& _k);
    };
    template<class T> void MyClass::Send(const T& _k) { std::cout<<"base template method"<<std::endl; }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    // MyClass.cpp
    template<>
    void MyClass::Send(const Item& _k) { std::cout<<"specialization for Item"<<std::cout; }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    // AnotherFile.cpp
    ...
    Item k;
    GetMyclass()->Send(k);
    ...
    Et c'est là que les ennuis commencent.

    Sans optimisation, en debug classique, la spécialisation est correctement appelée.
    Mais en Release/Master, optimisé, non ! Le linker ne tient pas compte de la spécialisation présente dans une autre unité de compilation.

    Pour résoudre ça : forward declaration de spécialisation template.
    Derrière ce nom barbare, une simple ligne template<> void MyClass::Send(const Item& _k); à placer dans le header.
    Donc le fichier devient:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    // MyClass.hpp
    class MyClass {
    public:
      template<class T> void Send(const T& _k);
    };
    template<class T> void MyClass::Send(const T& _k) { std::cout<<"base template method"<<std::endl; }
    template<> void MyClass::Send(const Item& _k);
    La spécialisation est à placer en dehors de la définition de la classe. Sinon vous serez victime d'un message d'erreur
    error : explicit specialization of 'Send' in class scope
    Notez que vous pouvez aussi implémenter la spécialisation dans le header, ce qui corrige également le problème. Mais c'est pas toujours possible. Ni très propre amha.

    C'était mes 2 centimes du jour, qui pourraient vous aussi vous sauver plusieurs heures/jours !
    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.

  2. #2
    Membre éclairé
    Inscrit en
    Décembre 2010
    Messages
    290
    Détails du profil
    Informations forums :
    Inscription : Décembre 2010
    Messages : 290
    Points : 719
    Points
    719
    Par défaut
    A vrai dire Bousk, bien que je sois loin d'être hyper à l'aise avec les templates, je ne comprends pas pourquoi ça marche en debug.

    Comment le compilateur peut-il savoir quelle spécialisation appeler si elle n'est pas au moins déclarée dans la même unité de compilation ?

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    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 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Après coup c'est facile de déclarer ça et on a eu la même réaction : "mais WTF que ça marchait en debug en fait ?! c'est totalement logique que ça marche pas! Comment en debug il pouvait trouver la spécialisation présente dans une autre unité de compilation ?"
    En tous cas c'est clair : en debug, sans optim, ça passe, en O3, ça casse. Je n'ai pas testé d'autres modes, mais c'est pas assuré que ça marche pas aussi avec O1 et O2 en optim.
    Bref, je voulais juste partager ce "trick" qui nous est apparus.
    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.

Discussions similaires

  1. Réponses: 4
    Dernier message: 15/10/2008, 09h33
  2. Spécialisation template et définition multiple
    Par loman02 dans le forum Langage
    Réponses: 10
    Dernier message: 23/04/2008, 13h48
  3. probleme spécialisation template
    Par babar63 dans le forum Langage
    Réponses: 23
    Dernier message: 30/10/2007, 14h42
  4. Réponses: 6
    Dernier message: 28/12/2006, 18h22
  5. Réponses: 5
    Dernier message: 17/06/2005, 19h26

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