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 :

Variadic template : ai-je loupé quelque chose ou est-ce un bug?


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    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 Variadic template : ai-je loupé quelque chose ou est-ce un bug?
    Salut,

    En préparant une réponse à cette discussion, j'ai été confronté à un comportement qui me semble étrange de la part de gcc...

    En effet, si j'exécute le code
    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
    29
     
    #include <string>
    #include <iostream>
    template<typename ...Args>
    void foo(Args ... args)
    {
        std::cout<<"stopping with "<<sizeof...(args)<< " unused arguments"<<std::endl;
    }
    template<typename ...Args>
    void foo(int i, Args ... args)
    {
        std::cout<<"using i = "<<i
                 <<", left "<<sizeof...(args)<<" argument more"<<std::endl;
        foo(args...);
    }
    template<typename ... Args>
    void foo(std::string const & s, Args...args)
    {
        std::cout<<"using the "<<s<<" string, left "
                 <<sizeof...(args)<<" argument more"<<std::endl;
        foo(args...);
    }
    int main()
    {
     
        foo<int, int,int, int, std::string , int, int >(1, 2, 3, 4,5 ,
                                                       "salut", 6, 7 );
        return 0;
    }
    l'exécution s'arrpête après avoir utiliser l'argument "salut", en me disant qu'il reste 2 arguments inutilisés.

    Par contre, si je rajoute une déclaration des fonctions sous la forme de
    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
    29
    30
    31
    32
    #include <iostream>
    #include <string>
    template<typename ...Args>
    void foo(int i, Args ... args);
    template<typename ...Args>
    void foo(std::string const & s, Args...args);
    template<typename ...Args>
    void foo(Args ... args)
    {
        std::cout<<"stopping with "<<sizeof...(args)<< " unused arguments"<<std::endl;
    }
    template<typename ... Args>
    void foo(std::string const & s, Args...args)
    {
        std::cout<<"using the "<<s<<" string, left "
                 <<sizeof...(args)<<" argument more"<<std::endl;
        foo(args...);
    }
    template<typename ...Args>
    void foo(int i, Args ... args)
    {
        std::cout<<"using i = "<<i
                 <<", left "<<sizeof...(args)<<" argument more"<<std::endl;
        foo(args...);
    }
    int main()
    {
     
        foo<int, int,int, int, std::string , int, int >(1, 2, 3, 4,5 ,
                                                       "salut", 6, 7 );
        return 0;
    }
    l'exécution va jusqu'à son terme...

    Je me serais pourtant attendu, étant donné que la définition de fonction vaut déclaration, à ce que le premier code fonctionne correctement !!!

    Alors, selon vous, aurais-je loupé quelque chose, ou s'agit-il d'un bug de gcc
    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

  2. #2
    Membre émérite
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2009
    Messages
    552
    Détails du profil
    Informations personnelles :
    Localisation : France

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

    Informations forums :
    Inscription : Mars 2009
    Messages : 552
    Par défaut
    Ton premier code arrive à terme avec ceci en sortie avec gcc 4.6.3

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    using i = 1, left 7 argument more
    using i = 2, left 6 argument more
    using i = 3, left 5 argument more
    using i = 4, left 4 argument more
    using i = 5, left 3 argument more
    stopping with 3 unused arguments

  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
    Citation Envoyé par bretus Voir le message
    Ton premier code arrive à terme avec ceci en sortie avec gcc 4.6.3

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    using i = 1, left 7 argument more
    using i = 2, left 6 argument more
    using i = 3, left 5 argument more
    using i = 4, left 4 argument more
    using i = 5, left 3 argument more
    stopping with 3 unused arguments
    Ben oui, et c'est justement là le problème...

    Je me serais attendu à ce que le premier code fournisse exactement la même sortie que le second, vu que les surcharges représentent le "best match" à chaque fois

    Mais, avant d'envoyer un rapport de bug, j'aimerais savoir ce que vous en pensez, au cas où je serais passé à coté d'un détail

    (note que j'ai ce comportement que je crois erroné avec gcc 4.7.1 "build perso" )
    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
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    Même résultat que Bretus : le programme s'arrête avant d'utiliser la spécialisation pour string, pas après. Donc résultat normale, la fonction spécialisée pour int ne peut pas appeler la spécialisation pour string (qui est déclarée après) et appelle donc la version non spécialisée (le stop)
    Donc pas de bug de notre côté (gcc 4.8 linux chez moi). Teste avec un build non perso (ou poste un draft pour modifier la norme C++ pour qu'elle respecte ton build perso ? )

  5. #5
    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
    Citation Envoyé par gbdivers Voir le message
    Même résultat que Bretus : le programme s'arrête avant d'utiliser la spécialisation pour string, pas après. Donc résultat normale, la fonction spécialisée pour int ne peut pas appeler la spécialisation pour string (qui est déclarée après) et appelle donc la version non spécialisée (le stop)
    Donc pas de bug de notre côté (gcc 4.8 linux chez moi). Teste avec un build non perso (ou poste un draft pour modifier la norme C++ pour qu'elle respecte ton build perso ? )
    En fait, je me doute bien que toutes les versions actuelles présentent le meme comportement, donc cela ne sert pas à grand chose de me confirmer que c'est celui que vous obtenez.

    Par contre, étant donné que tout est inline, il ne devrait pas y avoir une approche plus ou moins SFINAE qui ferait que les deux codes devraient réagir de la même manière

    Parce que l'on est quand même bien d'accord sur le fait que le compilateur commence à implémenter les fonctions quand il rencontre l'appel dans main.

    A ce moment là, il a déjà vu les définitions de toutes les surcharge et doit donc choisir le best match, même si la surcharge utilisant la std::string arrive après celle utilisant int.

    Autrement, cela veut dire que tu auras un comportement différent en fonction de l'ordre de tes paramètrex ou de l'ordre dans lequel tu définis tes surcharges, et ca, ca ne me semble pas normal du tout:

    Cela signifierait, avec le code tel qu'il est dans mon premier exemple, que si tu remplace l'appel par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    foo<std::string , int, int,int, int, int, int >( "salut",1, 2, 3, 4,5 ,
                                                       6, 7 );
    tu verrais tous les arguments...

    Ca me semble quand meme un peu suspect, non
    C'est pour cela que je demande si j'ai loupé quelque chose
    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

  6. #6
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    Ok, je comprend ce que tu veux dire... je pensais que tu disais que chez toi, le compilateur s'arrêtait après la spécialisation string, pas avant (donc un résultat différent de nous)
    Du coup, je sais pas trop

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

Discussions similaires

  1. Oh mince ! Quelque chose s'est mal passé.
    Par FoX_*D i E* dans le forum Debian
    Réponses: 3
    Dernier message: 29/10/2013, 18h06
  2. Template, oublirais-je quelque chose?
    Par koala01 dans le forum Langage
    Réponses: 8
    Dernier message: 28/08/2013, 13h41
  3. Boucles imbriquées - j'ai loupé quelque chose ?
    Par senacle dans le forum Général Python
    Réponses: 2
    Dernier message: 10/12/2007, 10h22
  4. Bug ? Ou quelque chose s'est passé sur mon ordi ?
    Par souviron34 dans le forum Mode d'emploi & aide aux nouveaux
    Réponses: 3
    Dernier message: 06/09/2007, 16h36
  5. Réponses: 3
    Dernier message: 27/04/2004, 18h21

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