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 :

l'expression doit avoir un type arithmétique ou pointeur


Sujet :

C

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 54
    Points : 32
    Points
    32
    Par défaut l'expression doit avoir un type arithmétique ou pointeur
    Bonjour,

    Lors de la réalisation d'un exercice, je suis tombé sur une erreur que je ne comprend pas.

    J'ai trouvé la solution, mais je n'en comprend pas la raison.

    J'ai donc une fonction de type int depuis laquelle je retourne une valeur:

    Le prototype de ma fonction

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int init_stGestMsg(int *pRC);
    L'appel depuis le main

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    	if (init_stGestMsg(&pRC) == GM_ERROR)
    	{
    		puts(GM_INIT_ERROR);
    	}
    	else
    	{
    		puts(GM_INIT_OK);
    	}

    et la fonction
    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
     
    int init_stGestMsg(int *pRC)
    {
     
     
    	// -------------------------------------------------------------------------------------------------------
    	// Initialisation des variables
    	etGestMsg stGestMsg = {NULL, 0, 5};
     
    	stGestMsg.dTailleBlocMax = stGestMsg.dTailleBloc;
     
    	// -------------------------------------------------------------------------------------------------------
    	// Création du tableau de messages TabMsg
    	if ((stGestMsg.tTabMsg = malloc(stGestMsg.dTailleBloc * sizeof(char*))) == NULL)
    	{
    		return GM_ERROR;
    	}
    	else
    	{
    		return GM_OK;
    	}
     
    }

    jusque la tout va bien..

    Mais en relisant l'exercice demandé par le prof, je m’aperçois qu'il demande à ce que la fonction soit de type void.

    du coup j’édite le type de la fonction avec un void et je fais les modif dans la fonction comme ceci

    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
    void init_stGestMsg(int *pRC)
    {
     
     
    	// -------------------------------------------------------------------------------------------------------
    	// Initialisation des variables
    	etGestMsg stGestMsg = {NULL, 0, 5};
     
    	stGestMsg.dTailleBlocMax = stGestMsg.dTailleBloc;
     
    	// -------------------------------------------------------------------------------------------------------
    	// Création du tableau de messages TabMsg
    	if ((stGestMsg.tTabMsg = malloc(stGestMsg.dTailleBloc * sizeof(char*))) == NULL)
    	{
    		*pRC = GM_ERROR;
    	}
    	else
    	{
    		*pRC = GM_OK;
    	}
     
    }
    et j'ai l'erreur dans le main dont je parlais et que je ne comprend pas ou il souligne ma fonction en rouge et me dit que "l'expression doit avoir un type arithmétique ou pointeur"

    La solution que j'ai trouvé est d'ajouter une * apres le void dans le prototype

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void * init_stGestMsg(int *pRC);
    et de faire de même dans le fichier de la fonction évidemment..

    En chipotant, je me rend compte que c'est a cause de l'inclusion de l'appel de fonction dans mon If
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (init_stGestMsg(&pRC) == GM_ERROR)
    que cela pose problème, et que si j'appelle la fonction en dehors du If, je n'ai pas besoin de rajouter l'* après le void..

    Et c'est la qu'est ma question.. Pourquoi???

  2. #2
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Une fonction retournant void ne retourne...... rien. Tu ne peux pas comparer ce qu'elle retourne à quelque chose si ta fonction ne retourne rien ! Pourtant, c'est ce que tu fais ici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (init_stGestMsg(&pRC) == GM_ERROR)
    Si en revanche ta fonction retourne void*, alors elle ne renvoie pas rien : elle renvoie un pointeur*. Tu peux donc comparer ton pointeur à quelque chose.

    Néanmoins, je suis étonné que ton compilateur n'émette pas d'autres warnings. Comment compiles-tu ? Quelle option passes-tu à ton compilateur ?

    *: si "rien" est désigné par "void", il ne faut pas croire que "void*" est un pointeur sur rien. C'est un pointeur sur quelque chose dont on ne précise pas le type. "void*" est un type spécial en C permettant de retourner un pointeur sur tout et n'importe quoi

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 54
    Points : 32
    Points
    32
    Par défaut
    Ah ok.. je me doutais que ca devait etre lié au If et a la comparaison du resutlat de la fonction.. mais je n'en étais pas sur.

    J'utilise VS 2017 et l'exercice se fait en C
    La seule option que je configure quand je crée un projet, c'est de changer le "Compiler en " -> "Compiler en code C (/TC)" dans les options avancées C/C++ des propriétés du projet.
    Et je n'ai aucune erreur de compil ou d'avertissements.
    Est ce que ca devrait??

    Est ce que ma façon de faire pourrait poser problème, peut être pas dans cette exercice en particulier mais dans des prg plus complexe??
    Est ce que de manière générale il vaut mieux séparer un appel de fonction et ensuite passer l'argument a un If??

    Si ca n'est pas une bonne méthode de dev, je préfère le savoir maintenant

    edit.. j'ai bien des warnings en fait

    1>fct_GestMsg.c
    1>...\gestionnaire_message.v2\fct_gestmsg.c(111): warning C4047: '=='*: les niveaux d'indirection de 'int' et de 'void *' sont différents
    1>...\\gestionnaire_message.v2\fct_gestmsg.c(106): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
    1>c:\program files (x86)\windows kits\10\include\10.0.14393.0\ucrt\string.h(129): note: voir la déclaration de 'strcpy'
    1>>...\\gestionnaire_message.v2\fct_gestmsg.c(75): warning C4716: 'init_stGestMsg' : doit retourner une valeur
    1>>...\\gestionnaire_message.v2\fct_gestmsg.c(121): warning C4716: 'gAddMsg' : doit retourner une valeur
    1>>...\\gestionnaire_message.v2\gestionnaire_message.v2\fct_gestmsg.c(160): warning C4716: 'afficheMsg' : doit retourner une valeur
    1>Gestionnaire_Message.V2.vcxproj -> >...\\Debug\Gestionnaire_Message.V2.exe
    1>Gestionnaire_Message.V2.vcxproj -> >...\\Debug\Gestionnaire_Message.V2.pdb (Partial PDB)
    1>Génération du projet "Gestionnaire_Message.V2.vcxproj" terminée.
    ========== Génération*: 1 a réussi, 0 a échoué, 0 mis à jour, 0 a été ignoré ==========

  4. #4
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Dunkhan Voir le message
    edit.. j'ai bien des warnings en fait
    Bonjour

    Un warning est un message signifiant "je ne suis pas certain d'avoir bien compris alors je vais tenter de coder ce que moi je comprends mais sans garantie". Ca ne veut pas dire que ça ne fonctionnera pas... mais ça ne garantit pas non plus que ça fonctionnera.
    Donc il vaut mieux faire en sorte de les supprimer...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 54
    Points : 32
    Points
    32
    Par défaut
    Moi qui pensait avoir trouvé un moyen d'optimiser mon code.. :/

  6. #6
    Expert éminent
    Avatar de Pyramidev
    Homme Profil pro
    Développeur
    Inscrit en
    Avril 2016
    Messages
    1 471
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 471
    Points : 6 109
    Points
    6 109
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Un warning est un message signifiant "je ne suis pas certain d'avoir bien compris alors je vais tenter de coder ce que moi je comprends mais sans garantie".
    Si on prend l'exemple « 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. », on ne peut pas dire que le compilateur n'est pas certain d'avoir compris.

    @Dunkhan,

    Un avertissement, c'est « J''accepte de compiler ce code. Mais, attention, on dirait qu'il contient des erreurs de programmation. »
    Parfois, c'est un faux positif. Par exemple, peut-être que, avant l'appel à strcpy(dest, src), tu as bien pris le soin de vérifier que strlen(str) était bien strictement inférieur au nombre de bytes dans le tampon pointé par dest.
    Mais il faut quand même se débrouiller pour que le code ne génère plus d'avertissements. Sinon, si on a 500 avertissements qui correspondent à des faux positifs, le jour où il y aura une vraie erreur de programmation détectée par un avertissement, ce nouvel avertissement sera noyé parmi les 500 avertissements et ne sera pas lu.

    S'aider des avertissements du compilateur pour détecter de potentielles erreurs de programmations permet d'éviter des bogues stupides comme celui-ci : https://www.developpez.com/actu/1222...t-open-source/
    Dans l'article dont j'ai donné le lien, la faille critique de sécurité venait d'un bogue qui venait d'une instruction zccoinSpend.denomination == libzerocoin::ZQ_WILLIAMSON; dans laquelle == aurait du être un =.
    Je ne sais pas quel(s) compilateur(s) les développeurs du projet utilisaient mais, avec GCC, avec l'option -Wall, une telle instruction provoque un avertissement « warning: equality comparison result unused ».

  7. #7
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 54
    Points : 32
    Points
    32
    Par défaut
    D'accord..
    Merci pour les précisions et l'article.

    Du coup je me demandais si il y avait moyen de formuler mon if pour ne pas déclencher ce genre de warning?

  8. #8
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 565
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    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 565
    Points : 7 648
    Points
    7 648
    Par défaut
    Le warning de ton if signale ici une erreur, il faut bien relire ce qui se passe pour tester la bonne chose. if (init_stGestMsg(&pRC) == GM_ERROR) n'a pas de sens, ce n'est pas le retour de la fonction qui détient le résultat, il faut faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    init_stGestMsg(&pRC);
    if (pRC == GM_ERROR)
    Et la variable n'est pas un pointeur, elle n'a aucune raison de s'appeler pRC.

  9. #9
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 54
    Points : 32
    Points
    32
    Par défaut
    Citation Envoyé par dalfab Voir le message
    Le warning de ton if signale ici une erreur, il faut bien relire ce qui se passe pour tester la bonne chose. if (init_stGestMsg(&pRC) == GM_ERROR) n'a pas de sens, ce n'est pas le retour de la fonction qui détient le résultat, il faut faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    init_stGestMsg(&pRC);
    if (pRC == GM_ERROR)
    Et la variable n'est pas un pointeur, elle n'a aucune raison de s'appeler pRC.
    La je reviens a ce que j'avais avant "d'optimiser" mon code..
    finalement, j'ai fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    init_stGestMsg(&pRC);
    	pRC == GM_ERROR ? puts(GM_INIT_ERROR) : puts(GM_INIT_OK);
    Pour le nom de variable, j'utilise la nomenclature fournie par le prof.. j'ai juste changer le nom de la fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Prototype : void gmInit (int *pRC);
    le code est dispo sur mon git https://github.com/Dunkh4n/Gestionna...ire_Message.V2
    Pour info, l'exercice va monter en complexité jusqu'a la version 5 avec des liste doublement chainée, une gestion de plusieurs gestionnaire de msg, ainsi qu'une gestion des msg d'erreurs..

  10. #10
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Le paramètre de la fonction est de type pointeur, le préfixe 'p' est cohérent. En revanche, la variable pRC que tu as créée dans ton main() n'est pas un pointeur. La preuve : tu en prends l'adresse pour obtenir un pointeur.

    RC = une variable "normale"
    &RC -> pRC = une adresse -> un pointeur

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pRC == GM_ERROR ? puts(GM_INIT_ERROR) : puts(GM_INIT_OK);
    La structure ternaire permet d'obtenir une valeur en fonction du résultat d'un test (résultat = test ? valeur si vrai : valeur si faux), contrairement à un if / else qui sert qu'à faire des actions différentes selon le résultat d'un test. On essaye en général d'utiliser la structure ternaire quand on veut obtenir une valeur, même si on peut souvent s'en servir comme d'un if/ else tel que tu l'as fait. Les programmeurs plus expérimentés utiliseront plutôt une de ces deux alternatives pour obtenir le même résultat (mais avec des intentions un peu différentes) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    if (pRC == GM_ERROR)
    {
        puts(GM_INIT_ERROR);
    }
    else
    {
        puts(GM_INIT_OK);
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    puts(pRC == GM_ERROR ? GM_INIT_ERROR : GM_INIT_OK);
    La différence est subtile, surtout quand on débute. Si tu ne comprends pas immédiatement la nuance, ce n'est pas très grave Garde ça dans un coin de ta tête pour plus tard.

  11. #11
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 54
    Points : 32
    Points
    32
    Par défaut
    Citation Envoyé par Bktero Voir le message
    Le paramètre de la fonction est de type pointeur, le préfixe 'p' est cohérent. En revanche, la variable pRC que tu as créée dans ton main() n'est pas un pointeur. La preuve : tu en prends l'adresse pour obtenir un pointeur.

    RC = une variable "normale"
    &RC -> pRC = une adresse -> un pointeur
    Corrigé.. J'avais copié la variable depuis le pdf sans réfléchir a faire la distinction..


    Citation Envoyé par Bktero Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pRC == GM_ERROR ? puts(GM_INIT_ERROR) : puts(GM_INIT_OK);
    La structure ternaire permet d'obtenir une valeur en fonction du résultat d'un test (résultat = test ? valeur si vrai : valeur si faux), contrairement à un if / else qui sert qu'à faire des actions différentes selon le résultat d'un test. On essaye en général d'utiliser la structure ternaire quand on veut obtenir une valeur, même si on peut souvent s'en servir comme d'un if/ else tel que tu l'as fait. Les programmeurs plus expérimentés utiliseront plutôt une de ces deux alternatives pour obtenir le même résultat (mais avec des intentions un peu différentes) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    if (pRC == GM_ERROR)
    {
        puts(GM_INIT_ERROR);
    }
    else
    {
        puts(GM_INIT_OK);
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    puts(pRC == GM_ERROR ? GM_INIT_ERROR : GM_INIT_OK);
    La différence est subtile, surtout quand on débute. Si tu ne comprends pas immédiatement la nuance, ce n'est pas très grave Garde ça dans un coin de ta tête pour plus tard.
    Oui, je crois que je comprend la nuance.

    La façon dont moi je l’écris, le résultat est une conséquence indirect alors que la tienne est le résultat direct.

    Dis autrement.
    Moi je fais une comparaison (pRC == GM_ERROR) qui va débouché sur une action dépendante de cette comparaison.
    Dans ta proposition, tu fais une action (le puts) dont le résultat va être déterminé par une comparaison?!

    De ce que je comprend, c'est important au niveau du compilateur et de la suite "logique" de la traduction en langage machine??


    J'ai mis a jour le git..
    https://github.com/Dunkh4n/Gestionnaire_Message.V2

  12. #12
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Dunkhan Voir le message
    De ce que je comprend, c'est important au niveau du compilateur et de la suite "logique" de la traduction en langage machine??
    Absolument pas. C'est juste plus factorisé comme expression donc considéré comme mieux écrit (juste d'un point de vue humain).

    Dit autrement: si demain tu voulais remplacer ton puts par printf, il te faudrait faire deux modifications dans ton code... alors que dans le code montré par Bktero il n'y a qu'une seule modification à effectuer. Code plus optimisé d'un point de vue écriture donc meilleur. Toutefois attention à ne pas pousser les choses à l'extrême car cela peut donner l'effet inverse. Voici pour illustrer un exemple de code trouvé sur un site de challenge de programmation...
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #define _(v,i,m)r=(v+=r-i)/m,v=v%m+i;
    main(a,b,f,g,c,r){a=b=f=g=0;scanf("%c%c-%3d-%c%c%d",&a,&b,&c,&f,&g,&r);_(c,1,999)_(g,65,26)_(f,65,26)_(b,65,26)_(a,65,26)printf("%c%c-%03d-%c%c\n",a,b,c,f,g);}
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  13. #13
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 54
    Points : 32
    Points
    32
    Par défaut
    oh.. ok ..

    Quand on débute, on va parfois chercher de la complication la ou il n'y en pas^^

    Je clos le topic, merci pour vos réponses

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

Discussions similaires

  1. Réponses: 146
    Dernier message: 05/10/2012, 17h47
  2. Réponses: 3
    Dernier message: 14/08/2007, 22h58
  3. distinct doit avoir une position particulière?
    Par robert_trudel dans le forum Access
    Réponses: 1
    Dernier message: 11/08/2006, 08h15
  4. Compilation avec Visual C++ 2005 Express pour avoir un module python
    Par Freyja dans le forum Déploiement/Installation
    Réponses: 6
    Dernier message: 13/07/2006, 12h12
  5. quel format doit avoir une BD pour l'importer avec copy?
    Par daknoom dans le forum PostgreSQL
    Réponses: 2
    Dernier message: 03/02/2005, 19h41

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