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 :

Un problème très étrange (difficile à décrire)


Sujet :

C++

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 77
    Points : 30
    Points
    30
    Par défaut Un problème très étrange (difficile à décrire)
    Salut.

    J'ai une classe Vecteur et une classe Corps

    voici les prototypes de leurs constructeurs:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Vecteur(unsigned int nombreComposantes, long double composante=0 );
    Corps(const Vecteur &position=Vecteur(2), const Vecteur &vitesse=Vecteur(2), const Vecteur &acceleration=Vecteur(2));
    Voici un bout de code pour que vous compreniez le problème:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    Corps corps1(Vecteur(3), Vecteur(3) , Vecteur(3)); // Pas de problème
    unsigned int a =3;
    Corps corps2(Vecteur(a), Vecteur(3) , Vecteur(3));//Pas de problème
    Corps corps3(Vecteur(a), Vecteur(3) , Vecteur(a));//Pas de problème
    Corps corps4(Vecteur(3), Vecteur(a) , Vecteur(a));//Pas de problème
     
    Corps corps5(Vecteur(a), Vecteur(a) , Vecteur(a));//Erreur "redefinition of 'Vecteur a' "  WTF ?
    Corps corps6(Vecteur(a), Vecteur(a) , Vecteur(3)); //Idem
    Vecteur v(a);
    Corps corps7(Vecteur(a), Vecteur(a) , v); //Idem
    Corps corps(v, v , v); //Pas de problème
    Si on pouvait m'expliquer ce qui se passe parce que là je comprend rien.


    Merci !

  2. #2
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    A première vue, je comprendrais ton problème si ton Idem signifie "pas de problème" et non pas "erreur". D'ailleurs, en compilant ton code, seule la ligne marquée explicitement "erreur", et pas les deux marquées idem, posent problème avec VC++2010.

    Pourquoi ? C'est un problème surnommé The C++ most vexing parse.

    Pour expliquer ce qui se passe, prenons le problème à l'envers. Comment ferais-tu pour déclarer une fonction, nommé f, qui retourne un objet de type Corps, et prend 3 paramètres entiers :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Corps f(int a, int b, int c);
    Maintenant, si les paramètres sont de type Vecteur, et la fonction nommée corps3 ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Corps corps3(Vecteur a, Vecteur b, Vecteur c);
    Maintenant, il est autorisé d'ajouter des parenthèses autour du nom des paramètres formels :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Corps corps3(Vecteur (a), Vecteur (b), Vecteur (c));
    Et là, c'est le drame...

    Car cette écriture pourrait s'interpréter comme la construction d'un objet de type Corps (la signification que tu voulais donner). Il y a ambiguïté dans le code, et dans ce cas, le compilateur est obligé de choisir la déclaration de fonction, plus que l'appel du constructeur. Pourquoi ? Parce que c'est comme ça, et qu'il fallait bien arbitrer dans un sens ou dans un autre.

    Du coup, le code que tu as écrit déclare une fonction, mais ses 3 paramètres formels ont le même nom, ce qui est interdit. D'où le message d'erreur, qui devrait désormais te sembler plus clair...
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  3. #3
    Membre éprouvé Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Points : 997
    Points
    997
    Par défaut
    Bonjour,

    Personnellement, j'ai des erreurs au trois lignes signalées.
    J'utilise g++ sous Linux.

    En essayant ce programme, j'ai pensé à rajouter le mot-clé « explicit » devant la déclaration des destructeurs, mais je me suis dit que ça n'aurait aucun impact.
    J'ai également pensé que le problème pourrait être dû au compilateur qui pense voir un simple parenthèsage de paramètre, comme l'indique JolyLoic, mais je ne voyais pas pourquoi il en serait ainsi.

    Son post me fait revenir sur mes précédentes conclusions…

    [edit]
    Finalement, le mot-clé « explicit » n'a effectivement aucune incidence…
    [/edit]

  4. #4
    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 519
    Points
    41 519
    Par défaut
    Maintenant, il est autorisé d'ajouter des parenthèses autour du nom des paramètres formels :
    Ça, c'est la connerie pour moi. Je ne vois pas pourquoi un truc pareil a été autorisé.

    @Cpowa: J'imagine que tu peux faire comme quand on veut forcer l'initialisation par défaut d'un type POD:
    Ce qui nous donnerait ici:
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    Corps corps5 = Corps(Vecteur(a), Vecteur(a) , Vecteur(a));
    Il me semble avoir lu ici que le compilo est en droit de supprimer l'appel au constructeur de copie dans le cadre de l'optimisation...
    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.

  5. #5
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Ça, c'est la connerie pour moi. Je ne vois pas pourquoi un truc pareil a été autorisé.
    Probablement par compatibilité avec le C...
    Mais mon hypothèse n'explique a priori pas le problème des lignes "Idem".
    Citation Envoyé par Médinoc Voir le message
    @Cpowa: J'imagine que tu peux faire comme quand on veut forcer l'initialisation par défaut d'un type POD:
    Ce qui nous donnerait ici:
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    Corps corps5 = Corps(Vecteur(a), Vecteur(a) , Vecteur(a));
    Il me semble avoir lu ici que le compilo est en droit de supprimer l'appel au constructeur de copie dans le cadre de l'optimisation...
    Ou plus simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Vecteur v(a);
    Corps corps5(v, v, v);
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 77
    Points : 30
    Points
    30
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    Probablement par compatibilité avec le C...
    Mais mon hypothèse n'explique a priori pas le problème des lignes "Idem".
    Effectivement ça n'explique pas l'erreur sur les autres ligne


    Citation Envoyé par JolyLoic Voir le message
    Ou plus simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Vecteur v(a);
    Corps corps5(v, v, v);
    Oui du coup j'utilise ça.

    Bizarre quand même...

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 77
    Points : 30
    Points
    30
    Par défaut
    Je sais pas si c'est lié au même problème mais j'ai le constructeurs de ma classe corps comme suit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Corps::Corps(const Vecteur &position, const Vecteur &vitesse, const Vecteur &acceleration, const long double masse, const std::string nom):
    m_position(position), m_vitesse(vitesse), m_acceleration(acceleration), m_nom(nom)
    {
        if(masse >0)
            m_masse= masse;
        else
            m_masse= masseTerre;
     
    }
    Pas de problème ça compile et ça fonctionne, mais j'ai décidé de rendre ça un peu plus propre en faisant quelques vérifications:

    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
    Corps::Corps(const Vecteur &position, const Vecteur &vitesse, const Vecteur &acceleration, const long double masse, const std::string nom): m_nom(nom)
    {
        if(position.size() == vitesse.size() && acceleration.size()==position.size())
        {
            m_position=position;
            m_vitesse=vitesse;
            m_acceleration=acceleration;
        }
        else
        {
     
            m_position=position;
            Vecteur vecteurNul(m_position.size());
     
            m_vitesse=vecteurNul;
            m_acceleration=vecteurNul;
        }
     
     
     
        if(masse >0)
            m_masse= masse;
        else
            m_masse= masseTerre;
     
    }
    La par contre ça veut plus compiler.
    J'ai "no matching function for call to 'Vecteur::Vecteur()'" sur la première ligne du constructeur.

    Je comprend pas...


    Merci de votre aide.

  8. #8
    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 519
    Points
    41 519
    Par défaut
    Pas de liste d'initialisation --> Les variables membres sont initialisées avec leur constructeur par défaut.
    Pas de constructeur par défaut pour Vecteur --> Erreur.
    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.

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

Discussions similaires

  1. Problème trés étrange
    Par laygen dans le forum ActionScript 1 & ActionScript 2
    Réponses: 0
    Dernier message: 09/08/2008, 17h05
  2. Problème très étrange !
    Par _SamSoft_ dans le forum Débuter
    Réponses: 3
    Dernier message: 15/09/2007, 17h44
  3. Réponses: 5
    Dernier message: 12/07/2007, 10h07
  4. problème très étrange avec mes tableaux
    Par lelutin dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 08/09/2006, 14h47
  5. Problème très étrange...
    Par TitiFr dans le forum Requêtes
    Réponses: 4
    Dernier message: 31/03/2005, 21h37

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