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 :

Problème "n'a pas été déclaré dans cette portée"


Sujet :

C++

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2022
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2022
    Messages : 3
    Par défaut Problème "n'a pas été déclaré dans cette portée"
    Bonjour,

    Je dois rendre un projet en programmation C++ et je rencontre un problème, j'ai créé une fonction qui renvoie une structure.
    Elle doit d'abord vérifier si un fichier existe et si celui-ci existe bien elle le met dans un vecteur de structure, cependant, au moment de renvoyer la structure elle me dit que le vecteur que j'ai déclaré n'a pas été déclaré dans cette portée.
    Pourriez vous donc me venir en aide ?
    Je vous mets ce que j'ai fais ainsi que l'énoncé du projet.

    (PS : N'hésitez surtout pas à me faire part d'éventuelles erreurs)

    En vous remerciant à l'avance,

    Cordialement

    Aiden
    Images attachées Images attachées    

  2. #2
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    C'est quoi le délire de perdre du temps à faire des captures d'images et les uploader quand on peut et devrait juste copier le texte ?!
    vecData n'existe pas sur la ligne du return.
    Relis ton cours sur les variables, elles ont une portée, généralement délimitée par les accolades {}. Et quand on arrive à la fin de celle-ci, tout ce qui s'y trouve est détruit.
    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.

  3. #3
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 639
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 639
    Par défaut
    Citation Envoyé par Bousk Voir le message
    C'est quoi le délire de perdre du temps à faire des captures d'images et les uploader quand on peut et devrait juste copier le texte ?!
    vecData n'existe pas sur la ligne du return.
    Relis ton cours sur les variables, elles ont une portée, généralement délimitée par les accolades {}. Et quand on arrive à la fin de celle-ci, tout ce qui s'y trouve est détruit.
    C'est d'ailleurs la raison pour laquelle l'instruction infile.close() ne sert strictement à rien: ta variable infile sera automatiquement détruite à la fin de la fonction abel, et, comme la classe ifstream est très intelligente, elle veillera en partant à fermer correctement le fichier qu'elle a ouvert.

    Au passage, tu te fais vraiment du mal pour rien avec les instruction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ifstream infile(a.c_str());
    infile.open(a);
    et cela, pour deux raisons:

    Primo, cela fait maintenant plus de dix ans que le constructeur de std::ifstream accepte une chaine de caractères de type std::string comme paramètre: ifstream infile(a.c_str()); pourrait donc sans aucun problème remplacé par ifstream infile{a}; et cela fonctionnerait tout aussi bien
    Deuxio, étant donné que tu as donné le nom du fichier à ta variable infile, le fichier est dores et déjà ouvert dés que la variable infile est créée. Il ne sert donc absolument à rien de demander à ta variable d'ouvrir le fichier qui t'intéresse, vu que ... elle l'a déjà fait

    Et pour t'aider à comprendre ton erreur: les fonctions représentent des contextes totalement différents, un peu comme si main prenait place au salon et qu'abel prenait place à la cuisine, la porte entre les deux étant fermée.

    Les seules possibilité pour interagir entre le salon et la cuisine étant, une boite à lettres sur la porte de la cuisine, pour y glisser les instructions concernant les repas depuis le salon et un passe plat pour permettre de recevoir les plats cuisinés dans la cuisine.

    Les paramètres des fonctions correspondant, dans le cas présent, à ce qui est transmis par la boite au lettre, et la valeur de retour correspondant à "ce qui est renvoyé" par le passe plats.

    Et bien sur, tout ce qui est au salon (et qui ne passe pas par la boite aux lettres) reste au salon, et tout ce qui est à la cuisine (et qui ne passe pas par le passe-plat)... reste à la cuisine

    Dans le cas présent, la donnée vecData représente l'assiette dans laquelle abel voudrait mettre le résultat de son travail. Seulement, comme cette est au salon et qu'elle ne passe pas par la boite aux lettres (note qu'elle pourrait ), ben, il ne sait pas l'utiliser

    Par contre, abel pourrait prendre une assiette directement dans la cuisine et l'utiliser pour y déposer le résultat de son travail avant de la faire passer par le passe plats
    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
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2022
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2022
    Messages : 3
    Par défaut
    Citation Envoyé par koala01 Voir le message
    La si je comprends bien ce que j'ai fais j'ai lus mon fichier et je l'ai mis dans mon vecData, cependant lorsque que fais infile.close tout est détruit ? du coup mon vecData ne vaut plus rien ?
    Il faudrait alors qu'un nouveau vecteur prenne les valeurs de mon vecData ?

    Citation Envoyé par Bousk Voir le message
    Je suis nouveau donc me dire tout simplement que pour la prochaine fois il faudrait copier le texte au lieu de mettre des captures aurait suffit merci
    Je ne comprend pas pourquoi mon vecData serait détruit lorsque je veux le retourner, j'ai bien déclaré mon vecteur de "ACM_Data" dans la fonction qui retourne un vecteur de structure ?
    Pourrais-je avoir plus d'indication.
    Merci

  5. #5
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Citation Envoyé par Aiden987 Voir le message
    Je ne comprend pas pourquoi mon vecData serait détruit lorsque je veux le retourner, j'ai bien déclaré mon vecteur de "ACM_Data" dans la fonction qui retourne un vecteur de structure ?
    Pourrais-je avoir plus d'indication.
    Merci
    Tout ce qui est défini dans ta fonction va disparaître quand ta fonction se termine. infile est détruit donc le ficher est automatiquement fermé comme on te l'a écrit. Et évidemment vecData est lui aussi détruit.
    Heureusement tu écris : return vecData;. Donc ce qui était dans vecData a été transmis à celui qui appelle la fonction. Il faut que tu récupères cette valeur dans main() quand tu appelles abel(instance), par exemple tu peux utiliser le même nom dans main() (mais c'est une toute autre variable même si tu lui donnes le même nom):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
            vector<ACM_Data>  vecData = abel(instance);     // Le vecData de main() récupère le résultat
    Et attention ta fonction retourne un vector<ACM_Data> pas un ACM_Data donc tu dois bien l'indiquer dans le prototype de ta fonction.

  6. #6
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 639
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 639
    Par défaut
    Citation Envoyé par Aiden987 Voir le message
    La si je comprend bien ce que j'ai fais j'ai lus mon fichier et je l'ai mis dans mon vecData, cependant lorsque que fais infile.close tout est détruit ? du coup mon vecData ne vaut plus rien ?
    Il faudrait alors qu'un nouveau vecteur prenne les valeurs de mon vecData ?
    Non, tu ne comprends pas bien

    Car ici, tu travailles avec deux données différentes:
    • d'un coté, tu as la variable infile, qui représente le fichier dans lequel on va aller lire les informations
    • et de l'autre, tu as la variable vecData (dont on va considérer qu'elle existe) qui est une collection (de données) dans laquelle tu vas ajouter progressivement les données que l'on aura extraites et interprétées à partir de infile

    Or, le langage est très précis sur la "durée de vie" des données qu'il manipule. Au lieu de te bazarder toutes la théorie en une seule fois et de tout t'expliquer par la suite, je vais plutôt te la donner "par étapes" qui seront à chaque fois expliquées:

    Règle N° 1: une donnée n'existe que dans le bloc d'instructions dans lequel elle a été déclarée.

    Un bloc d'instructions est, typiquement, représenté en C++ par une paire d'accolades. C'est à dire qu'une donnée (une variable) est connue par le compilateur entre le moment où on déclare cette donnée et l'accolade fermante qui la suit directement.

    Voici un exemple -- avec les explications qui vont bien -- de l'idée:
    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
     
    /* Soit une fonction "quelconque" */
    void foo()
    {           // début "premier" bloc d'instructions
        //avant la déclaration uneDonnee, le compilateur en ignore l'existence
        UnType uneDonnee;    //On déclare la donnée uneDonnee.  C'est à ce moment précis que le compilateur apprend que la donnée existe
        // uneDonnee est disponible ici
        /* on fait des trucs ici */
        if(une_condition_quelconque)
        {    //début du "deuxième" bloc d'instructions
             AutreType autreDonnee
             // autreDonnee est disponible ici
             // uneDonnee est aussi disponible, car nous sommes -- de manière indirecte -- toujours dans le "premier" bloc d'instructions
             /* on fait encore des trucs ici */
        }    //fin du "deuxième bloc d'instructions. autreDonnee cesse d'exister pour le compilateur à cet endroit précis 
        // uneDonnee est encore disponible, car nous sommes encore et toujours dans le "premier" bloc d'instructions
        /* on fait toujours des trucs ici */
    }    // fin du "premier bloc d'instructions .  uneDonnee cesse d'exister pour le compilateur à cet endroit précis
    Voilà, en quelques lignes de code, la manière dont le compilateur va comprendre ton code

    Règle N° 2: Les données cessent d'exister dans l'ordre inverse de leur déclaration:
    Cela signifie que si tu déclare plusieurs variables dans un bloc d'instructions identique, elles vont "commencer à exister" pour le compilateur dans l'ordre exacte dans lequel elles auront été déclarées, et qu'elles cesseront d'exister pour le compilateur, au moment où l'on atteint l'accolade fermante, dans l'ordre inverse de celui dans lequel elles ont été déclarées. Voici un exemple pour comprendre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    /* soit une fonction */
    void foo()
    {   début du bloc d'instructions
         // aucune donnée est connue du compilateur ici
         /* mais on peut quand même faire des trucs ici */
        UnType uneDonnee;//On déclare la donnée uneDonnee.  C'est à ce moment précis que le compilateur apprend que la donnée existe
        /* on peut faire d'autre trucs ici */
        AutreType autreDonnee; //On déclare la donnée autreDonnee.  C'est à ce moment précis que le compilateur apprend que la donnée existe
        /* on peut encore faire d'autres trucs ici */
        EncoreUnType encoreUneDonnee; //On déclare la donnée encoreUneDonnee.  C'est à ce moment précis que le compilateur apprend que la donnée existe
        /* il est encore possible de faire d'autres trucs ici */
    } // fin du bloc d'instructions : encoreUneDonnee -- qui a été déclarée en dernier est "oubliée" du compilateur en premier, 
      // ensuite, ce sera au tour de autreDonnee d'être "oubliée"
      // et, enfin, seulement, celui de uneDonnee
    Règle N°3: Si une donnée est renvoyée par une fonction , sa durée de vie est automatiquement étendue à la durée de vie de donnée qui la récupère (au niveau de la fonction appelante)

    Par contre, bien que la donnée soit encore "disponible", le compilateur aura "oublié" le nom sous lequel il "connaissait" la donnée dans la fonction appelée au niveau de la fonction appelante.

    voici un exemple:
    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
    /* soit une fonction quelconque */
    UnType foo()  // foo doit renvoyer une donnée de type UnType ;)
    {    // début du bloc d'instructions
         /*on fait des trucs ici */
        UnType uneDonnee; // je présume que tu as compris l'idée ? dois-je vraiment encore répéter le principe?
        /* on fait d'autre trucs ici */
        AutreType autreDonnée; //suis-je un vieux disque vinyle tout griffé ???
        /* on fait encore des trucs ici */
        return uneDonnee; // uneDonnee est renvoyée ici.  Elle ne sera donc "oubliée" par le compilateur
    }   // fin du blocs d'instructions : autreDonnee est oubliée du compilateur ici
        // Le compilateur "oublie" le nom uneDonnee, par contre, il s'apprête à  en utiliser les valeurs pour la donnée qui récupère le retour de la fonction
     
    /* et la fonction appelante: */
    void bar(){
        /* on fait des trucs ici */
        UnType result = foo(); // on déclare result comme étant de type UnType et comme ayant pour valeur la donnée renvoyée par foo
                                       // Le compilateur sait donc maintenant que result existe, et lui donne les valeurs de la donnée qu'il connaissait 
                                       // sous le nom de uneDonnee dans foo
        /* on fait d'autres trucs ici */
    }  // fin du bloc d'instructions de la fonction appelante: result est "oublié" ici
    Règle N° 4 : les agrégats de données (classes et structures) respectent scrupuleusement les trois premières règles

    Il faut cependant noter que des règles secondaire et tertiaire sont d'application:
    4-a: un constructeur sera automatiquement appelé lors de la déclaration d'une donnée dont le type est un agrégat de données
    4-b: un destructeur sera automatiquement appelé lorsqu'une donnée dont le type est un agrégat de données est "oubliée" par le compilateur

    On peut avoir facilement confirmation de ces deux règles secondaires, simplement au travers du code suivant
    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
    #include <iostream>
    /* un agrégat de données quelconque, même s'il n'en contient aucune ;) */
    struct  MaStruct  // il n'y a que très peu de différence entre le mot clé class et le mot clé struct
    {             // en tout cas, il n'y a aucune différence qui vaille la peine d'être citée ici ;)
        /* un constructeur */
        MaStruct(int i)
        {   // début du bloc d'instructions du constructeur  
            std::cout<<"Donnee de type MaStruct creee avec la valeur "<< i<<"\n";
        } // fin du bloc d'instructions du constructeur
        /* un destructeur  basique */
        ~MaStruct()
        {   // début du bloc d'instructions du destructeur
            std::cout<<"Donnee de type MaStruct detruite\n";
        } // fin du bloc d'instructions du destructeur
    };
    /* et une utilisation potentielle de cet agrégat de données */
    int main()
    {  // début du bloc d'instructions de la fonction
        for(int i=0; i<10; ++i)
        { // début du bloc d'instructions de la boucle
            std::cout<<"dans la boucle "<<i<<":\n";
            MaStruct laDonnee{i+1};
        }  // fin du bloc d'instructions de la boucle, laDonnee est "oubliée" (et son destructeur appelé)
    }
    Regle N°5: les donnée qui composent un agrégat respectent scrupuleusement les quatre première règles:

    Il faut cependant ajouter quelques règles "secondaires, à savoir que:
    5-a les données qui composent l'agrégat sont créées avant l'agrégat en lui-même: si tu as une structure qui contient trois entiers, les entiers qui composent cette structure seront créés en premier, et ce n'est qu'après que "l'emballage" de la structure en elle-même sera créé.
    5-b Le constructeur des données qui composent l'agrégat de donnée sera appelé avant même que le contenu du constructeur de l'agrégat ne soit exécuté
    5-c La durée de vie des données qui composent l'agrégat est celle de la donnée dont le type est l'agrégat en lui-même
    5-d lorsqu'un agrégat est détruit, le destructeur de l'agrégat est exécuté avant que les données qui le composent ne soit détruites (et leur destructeur respectif appelé, s'il échoit)

    Comme le code d'exemple devient un peu long, je vais supprimer la plupart des commentaires (pour lesquels j'espère que tu a compris le principe ). Par contre, le code présenté peut être compilé et exécuté chez toi, et tu peux même te faire une idée de son résultat directement ==>ICI<==.
    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
    33
    34
    35
    36
    37
    38
    39
    #include <iostream>
    /* un premier type personnalisé de "donnée interne" */
    struct UnType{
        int i;
        UnType(int i):i{i}{
            std::cout<<"UnType cree avec la valeur "<<i<<"\n";
        }
        ~UnType(){
            std::cout<<"UnType ayant i = "<<i<<" détruit\n";
        }
    };
    /* un deuxième type personnalisé de "donnée interne" */
    struct AutreType{
        int j;
        AutreType(int j):j{j}{
            std::cout<<"AutreType cree avec la valeur "<<j<<"\n";
        }
        ~AutreType(){
            std::cout<<"AutreType ayant j = "<<j<<" détruit\n";
        }
    };
    /* ma structure de test */
    struct MaStruct{
        MaStruct(int i, int j):uneDonnee{i}, autreDonnee{j}{
            std::cout<<"MaStruct cree avec les valeurs\n"
                     <<" i = "<<i<<"\n"
                     <<" j = "<<j<<"\n";
        }
        ~MaStruct(){
            std::cout<<"MaStruct detruite\n";
        }
        UnType uneDonnee;
        AutreType autreDonnee;
    };
    int main(){
        for(int i=0; i<10; ++i){
            MaStruct data{i+1, i+11};
        }
    }
    Ce qu'il faut en retenir:
    Déjà, il faut en retenir que, si on n'a pas recours à l'allocation dynamique de la mémoire (c'est d'ailleurs un point que je n'ai absolument pas abordé, mais ce sera pour une autre fois ), on sait exactement ce qui sera fait, à quel moment et dans quel ordre.

    En gros, c'est simple: on construit à la déclaration, dans l'ordre des déclarations, on détruit lorsque l'on quitte le bloc d'instructions, dans l'ordre inverse des déclarations

    Il faut aussi savoir que la construction et la destruction sont strictement automatiques et ont pour objectif de respecter deux buts essentiels:
    1. Chaque donnée créé -- aussi complexe puisse-t-elle être -- est, à tout le moins, dans un état cohérent lui permettant d'être utilisée (respecte les "invariants" imposés par le type de donnée qui la représente) dés le moment de sa création.
    2. Chaque donnée détruite "fait le ménage" et "nettoie les crasse qu'elle a pu faire" avant de partir (et d'être détruite)

    Dans l'idéal, nous essayerons même de faire en sorte que chaque donnée créée soit dans un état qui ne nécessite "aucune intervention supplémentaire" avant d'être effectivement utilisable par la personne qui la créée.

    C'est la raison pour laquelle nous conseillons généralement d'attendre le "tout dernier moment" avant de déclarer les variables (alors qu'il fut un temps en C où l'on était obligé de les déclarer en tout début de fonction / de bloc d'instructions), parce que cela nous donne "une possibilité supplémentaire" de faire en sorte que la création fournisse une donnée "prête à l'emploi" (par exemple: qui aurait déjà ouvert le fichier qu'elle est sensée lire) en fournissant les informations "qui vont bien" au constructeur.

    C'est aussi la raison pour laquelle une classe comme std::ifstream nous propose plusieurs constructeurs, parmi lesquels on peut très certainement citer:
    1. un constructeur prenant le nom du fichier ("texte") qui devra être ouvert, car cela lui permet d'avoir déjà ouvert le fichier lorsque l'utilisateur est en mesure de l'utiliser
    2. un constructeur ne prenant pas de paramètres, et qui nécessite donc de faire appel à la fonction open en lui fournissant le nom du fichier qui doit être ouvert (et le cas échéant, d'autres informations)

    Et c'est enfin dans cette optique de "faire le ménage avant de partir" que le destructeur de la classe std::fstream va s'assurer de fermer le fichier qui aura (éventuellement) été ouvert,afin de le "remettre en état" pour "l'utilisation suivante"

    Cependant, il n'y a "rien de mal fait" si tu appelle la fonction close (à un moment adéquat, du moins) de la classe std::fstream: tu ne fais que ... fermer le fichier qui est utilisé pour la lecture, et, si tu ne dois plus le lire par la suite, ce n'est sans doute "pas plus mal"

    Le seul truc, c'est que c'est "inutile" si la variable de type std::ifsteam qui manipule ce fichier est destinée à être détruite directement après, parce que la destruction de la variable de type std::ifstream (ta variable infile) provoquera ** forcément ** la fermeture du fichier dans lequel elle lisait
    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. [11g] PLS-00222: la fonction nommée X n'existe pas dans cette portée
    Par strompakha dans le forum PL/SQL
    Réponses: 2
    Dernier message: 18/10/2019, 13h55
  2. stepper n'est pas déclaré dans le scope
    Par Mathieugalère dans le forum Arduino
    Réponses: 8
    Dernier message: 18/03/2019, 22h44
  3. [Oracle] ORA-08002: séquence pas encore définie dans cette session
    Par cornnery dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 20/03/2009, 17h22
  4. Réponses: 2
    Dernier message: 11/02/2008, 22h02
  5. Séquence pas encore définie dans cette session
    Par hair_peace dans le forum Oracle
    Réponses: 2
    Dernier message: 03/11/2005, 17h04

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