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 :

Critique envers le C++


Sujet :

C++

  1. #1
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    Par défaut Critique envers le C++
    Salut à tous.
    Je suis en train de lire le livre Conception et programmation orientées objet par Bertrand Meyer.

    1er salve de critiques:
    Dans le chapitre 14 qui est consacré à l'héritage, il analyse les choix fait par le comité du C++ en ce qui concerne les techniques de liaisons.

    Il relève les points suivants:
    C1: rendre le programmeur responsable du choix de la liaison (statique ou dynamique)
    C2: utiliser la liaison statique par défaut.

    Il relève C1 car selon lui, ce genre de choix tient des compilateurs et non des programmeur, qui devrait se concentrer sur autre chose.
    Il en tire aussi la conséquence que C1 viole le principe ouvert-fermé, car choisir si la fonction doit être virtuelle ou non force revient à deviner ce que les classes héritières vont pouvoir redéfinir, et bloque ainsi toute évolution (Pour note, dans le langage étudié, toute liaison est dynamique par défaut, c'est le compilateur qui décide s'il peut la rendre statique).

    En ce qui concerne C2,je dois d'abord planter le contexte. Selon lui la liaison statique est une optimisation.En effet, certain appels de fonction ne nécessite pas de liaison dynamique, mais comme dans le langage étudié toute liaison est dynamique, la remplacer par une liaison statique quand c'est possible enlève le sur-coût lié à l'appel dynamique, et c'est donc une optimisation: CQFD.

    Après, selon lui :
    Une liaison statique est sémantiquement incorrecte sauf si son effet est identique à celui de la liaison dynamique
    ce qui semble logique car dans un contexte polymorphique, un appel à une fonction redéfinie dans une classe B via un pointeur de type A (A parent de B) doit appeler la version redéfinie. Et enfin plus loin il résume sa vision à :
    La liaison statique est soit une optimisation soit un bogue.
    On en arrive donc au cœur du problème, le C++ force à écrire quelque chose de spécial pour arriver à une sémantique correcte.

    Pour résoudre C1 et C2 en même temps, il propose de rendre tout appel de fonction virtuel par défaut et ajouter un mot clé pour utiliser la liaison statique.

    Dans l'état actuel des choses pour solutionner le problème, il propose de mettre toutes les fonctions membres virtuelles pour contrer C1 et C2, ce qui est paradoxal car cela augmente les temps d'exécution alors que justement C1 et C2 sont présentes pour les diminuer.

    Enfin après, il cite un livre de Walter Bright datant de 1995 qui recommande de limiter les technologies Objets (polymorphisme, héritage multiple) à cause des question de coût temporel. je pense que ca a été vrai par le passé mais que ça ne l'est plus.

    2eme salve:
    Elle concerne le mélange surcharge de fonction ad hoc (via signature) couplé au polymorphisme. Pour résumer, il pense que ca met un bordel par possible dans le choix de la fonction à appeler tout en n'apportant rien au langage. Il conseille donc de bannir cette forme de surcharge.

    Que pensez vous de ces critiques ?
    Pour ma part, je pense que les critiques liées à C1 et C2 sont globalement justes, même si on peut résoudre le problème avec l'utilisation du pattern template method (en gros, chaque fonction foo d'une ABC fait appel à une fonction virtuelle do_foo qui réalise vraiment foo).

    Par contre pour la 2eme salve, je suis plutôt choqué. Bien que les rêgles de surcharge soit assez ésotériques, la surcharge ad hoc permet des chose très puissantes comme par exemple l'uniformité des interfaces (surcharge de operator<< qui permet d l'utiliser quelque soit le type de l'objet) alors que dans son langage, on dispose de fonction tel put_ligne, ....

    Merci.

    EDIT: La discussion ayant été supprimé à cause du rollback, ci joins l'ensemble des messages de la première discussion, si un admin pouvait les restaurer, merci.
    Fichiers attachés Fichiers attachés
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  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
    [Je ne pense pas qu'il y ait de restauration automatique possible, bien entendu, les gens peuvent toujours reposter tout dans le même ordre ]

    Pour ma part, je suis en désaccord avec les deux salves, et c'est justement pour des principes associés à la programmation par contrat que je suis en désaccord avec la première...

    Pour moi, la (non)virtualité d'une fonction n'est absolument pas une histoire d'optimisation, mais avant tout une histoire de contrat. Si je rend une fonction virtuelle, j'étends par là le contrat de cette fonction, puisqu'en plus de ses préconditions et postconditions, je me retrouve à devoir spécifier de quelle manière je compte utiliser cette fonction dans le reste de ma classe.

    Par exemple, une fonction draw dans l'exemple archétypal du logiciel de dessin vectoriel. En non virtuel, je dois préciser dans quelles conditions on peut l'appeler (la surface de dessin a été initialisée), ce qu'elle va faire (après son appel, la surface de dessin contiendra une représentation de la figure. Et c'est tout.

    Si je rends la même fonction virtuelle, j'ajoute des éléments au contrat. Par exemple, je garanti que tous les dessins de la forme seront effectués à l'aide de cette fonction. Et que je vais tenter de l'appeler aussi peu souvent que possible (car une version dérivée pourrait être bien plus gourmande que ma version de base). Je vais aussi devoir préciser toute une série de pré/post condition qu'il n'était pas nécessaire/utile de connaître auparavant (Que le nombre d'objets crayon vivant à la sortie de la fonction et le même que le nombre entrant, que de toute façon, sur la surface de dessin, tout ordre en dehors de la bounding box de l'objet sera ignoré,...

    Tout ça a un coût (quand c'est possible), et si je suis près à payer ce coût en blindage de design, documentation(1), rigidité du résultat... pour les quelques points d'extensibilité de mes classes, je ne suis clairement pas prêt à le payer pour toutes mes fonctions.

    Je ne crois pas qu'on puisse avoir une extensibilité au hasard, en mettant toutes les fonctions en virtuel, au cas où un utilisateur voudrait en faire quelque-chose. Pour moi, pour marcher, l'extensibilité doit être limitée à des directions planifiées par le designer de la classe de base.

    Pour le second point, je suis persuadé que même en Eiffel, on peut écrire 1+1 et 1.2+ 3.14...

    (1) J'ai d'ailleurs régulièrement à souffrir avec des docs d'IHM qui décrivent une fonction virtuelle comme si elle ne l'était pas. On sait à peu près ce qui se passe quand on appelle la fonction en question, mais on n'a aucune idée de ce qu'on est sensé faire si on décide de remplacer cette fonction par notre propre version. En général, deux solutions : Lire le code source, ou procéder par essai/erreur avec ajout de traces afin d'essayer de reconstituer l'état d'esprit de la personne ayant écrit le code initial...
    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
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    J'aime bien Bertrand Meyer mais il s'appuye sur ses principes jusqu'a les faire craquer (ce qu'il faut toujours faire)... Malheureusement, ici ce n'a pas l'air volontaire. Remarquer que la resolution des membres virtuels n'est qu'une surcharge resolue dynamiquement me fait me demander pourquoi Eiffel ne propose pas le dispatch multiple. Sa position serait beaucoup plus coherente.

    (Au fait, dans quelle mesure est-ce que ce bouquin est different de Conception et programmation par objets?)
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  4. #4
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    Par défaut
    Pour répondre aux messages de Sylvain Togni et en partie zais_ethael .
    C'est vrai qu'on utilise tellement le C++ pour le coté objet qu'on peut oublier qu'il est hybride et ne se borne pas à l'objet mais permet aussi de faire du procédural, de la progrmmation logique (avec Castor C++). Et dans ces contextes, utiliser la liaison dynamique n'a pas de sens car il 'y a pas d'objet .

    Pour moi, la (non)virtualité d'une fonction n'est absolument pas une histoire d'optimisation, mais avant tout une histoire de contrat. Si je rend une fonction virtuelle, j'étends par là le contrat de cette fonction
    Ce point de vue ne marche qu'avec un langage au à liaison statique. En Eiffel, un contrat c'est {post/pré}conditions de la routine + invariant de classe. La virtualité étant activée par défaut, elle ne peut faire partie du contrat alors qu'en C++, si.

    Je ne crois pas qu'on puisse avoir une extensibilité au hasard, en mettant toutes les fonctions en virtuel, au cas où un utilisateur voudrait en faire quelque-chose. Pour moi, pour marcher, l'extensibilité doit être limitée à des directions planifiées par le designer de la classe de base.
    C'est vrai que certaines choses dans ne classe ne devrait pas être redéfini. Ici, la liaison statique prend donc tout son sens .

    Pour le second point, je suis persuadé que même en Eiffel, on peut écrire 1+1 et 1.2+ 3.14...
    Il faut préciser qu'en eiffel, tout est classe, même les nombres. Donc faire 1+1 va appeler l'opérateur + redéfinie dans la classe INTEGER alors que 1.2+3.14 va faire appel à l'opérateur défini dans la classe REAL.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  5. #5
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par Davidbrcz Voir le message
    Il faut préciser qu'en eiffel, tout est classe, même les nombres. Donc faire 1+1 va appeler l'opérateur + redéfinie dans la classe INTEGER alors que 1.2+3.14 va faire appel à l'opérateur défini dans la classe REAL.
    Ca ne regle pas 1 + 42 par rapport a 1 + 3.14 -- a moins qu'Eiffel soit aussi rigide que ML and co la dessus et donc que ce que je disais a propos des principes sur lesquels on s'appuye jusqu'a les faire craquer est vrai.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  6. #6
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    Par défaut
    (Au fait, dans quelle mesure est-ce que ce bouquin est different de Conception et programmation par objets?)
    Je ne peut répondre, je ne trouve pas le sommaire de ce livre, je donne donc le sommaire du livre que j'ai en ma possesion:
    • Les problèmes
      • La qualité du logiciel
      • Critères d'orientation objet

    • La route de l'orientation objet
      • Modularité
      • Approches de la réutilisabilité
      • Vers la technologie objet
      • Types abstraits de données

    • Techniques orientées objet
      • La structure statique : les classes
      • La structure à l'exécution : les objets
      • Gestion de la mémoire
      • Généricité
      • Conception par contrat : construire du logiciel fiable
      • Quand le contrat est rompu : le traitement des exceptions
      • Mécanismes supplémentaires
      • Introduction à l'héritage
      • Héritage multiple
      • Techniques d'héritage
      • Typage
      • Objets globaux et constantes

    • Méthodologie orientée objet : bien appliquer la méthode
      • De la méthodologie
      • Schéma de conception : systèmes interactifs à écrans multiples
      • Etude de cas d'héritage : "défaire" dans un système interactif
      • Comment trouver les classes
      • Principes de conception des classes
      • Bien utiliser l'héritage
      • Techniques utiles
      • Un penchant pour le style
      • Analyse orientée objet
      • Le processus de construction logicielle
      • Enseigner la méthode

    • Aspects avancés
      • Concurrence, répartition, client-serveur et Internet
      • Persistance d'objets et bases de données
      • Quelques techniques OO pour applications graphiques interactives

    • Appliquer la méthode dans divers langages et environnements
      • Programmation OO et Ada
      • Emulation de la technologie dans les environnements non OO
      • De Simula à Java et au-delà : principaux langages et environnements OO

    • Faire les choses bien
      • Un environnement orienté objet
      • Epilogue : le langage dévoilé
    • Annexes

      • A. Extraits des bibliothèques Base
      • B. Généricité et héritage
      • C. Glossaire de la technologie objet
      • D. Bibliographie
    • Index


    Ca ne regle pas 1 + 42 par rapport a 1 + 3.14 -- a moins qu'Eiffel soit aussi rigide que ML and co la dessus et donc que ce que je disais a propos des principes sur lesquels on s'appuye jusqu'a les faire craquer est vrai.
    je viens de tester (je découvre encore l'eiffel) et non ca compile bien, et il est vrai que je en sais pas comment il fait car:
    • Chaque opérateur d'une classe représentant un nombre décrivant une opération recoit un objet du même type (REAL + attend un REAL, de même pour les INTEGER)
    • Les cast utilisateurs sont interdit. Mais vu que c'est traduit en C au final, faut voir.

    Peut être un coup de polymorphisme avec NUMERIC
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 064
    Points : 1 053
    Points
    1 053
    Par défaut
    Citation Envoyé par Davidbrcz Voir le message
    C'est vrai qu'on utilise tellement le C++ pour le coté objet qu'on peut oublier qu'il est hybride et ne se borne pas à l'objet mais permet aussi de faire du...
    Heu... ce n'est pas du tout ce que j'ai voulu dire. Une petite précision tout d'abord: il faut savoir que pour moi l'utilisation de structures (NDLR: les structures et les classes c'est kif-kif en C++) avec méthodes, constructeurs et accessibilité est une fonctionnalité présente dans la plupart des langages à objet mais que cela est tellement réducteur par rapport au concept de l'orienté objet que ça n'en est pas. Pour moi orienté objet est complètement indissociable de polymorphisme objet, à tel point que je les considère comme synonymes. Bon, ça c'est dit.

    En sachant cela, le polymorphisme objet est loin, très loin de constituer la majeure partie des programmes en C++. Si on prend Boost par exemple, les concepteurs y semblent complètement allergiques, la métaprogrammation est largement plus utilisée chez eux. Et il faut reconnaitre que ça donne un style bien plus naturel qu'une utilisation d'interfaces par exemple (avec tous les problèmes de gestion de mémoire que ça engendre).

  8. #8
    Alp
    Alp est déconnecté
    Expert éminent sénior

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    Pour ma part, je pense juste que les auteurs de bibliothèques de Boost ont su réfléchir à quand il est vraiment nécessaire de créer une hiérarchie de classes ou alors quand il fallait simplement faire une fonction libre surchargées/spécialisée, ce genre de choses... Le code de Boost est probablement celui qui exploite le mieux les possibilités du C++ actuel... et ce sera aussi le cas pour C++0x à mon avis.

    Boost devient vraiment une source d'informations sur le C++ monstrueuse et enseigne mieux que quiconque quelles sont les bonnes pratiques.

  9. #9
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Concernant les fonctions virtuelles ou pas.
    Loïc a déjà évoqué le NVI et le fait que ce n'est pas parce qu'une fonction est virtuelle que l'on peut la supplanter comme si rien n'était. On pourrait quasi y arriver en respectant la règle "une fonction une responsabilité", mais ...

    Un truc important qui a été sous-entendu, c'est que "virtual" sert de documentation à destination des classes filles. On dit : "tu peux supplanter cette fonction, n'ait pas peur, c'est fait pour". Du coup, quand on se retrouve avec la classe entre les mains, comment savoir laquelle des 50 fonctions doit (et peut) être supplantée? Cela relève du même principe que celui de l'encapsulation : on expose des détails sur lesquels on croit pouvoir jouer. On a un contrat plus seulement à destination du code client, mais aussi entre générations d'une même famille de classes.

    Autre problème : cela n'a aucun sens pratique sur les classes à sémantique de valeur (sans faire des contorsions pour éviter les slicings)

    Je sais que d'autres ont une vision assez opposée. L'approche du C++ me plait assez. J'étais tombé sur deux lectures à ce sujet : http://www.artima.com/intv/meaningP.html et http://www.artima.com/intv/nonvirtual.html



    Concernant la surcharge. C'est certes un sucre syntaxique. Mais l'interdire pour revenir à la situation du C, où l'on a 20 occurrences de la même fonction avec juste un post-fixage différent pour les 20 types entrants possibles (cf math.h), me parait particulièrement maladroit.


    EDIT: autre lecture à considérer : le document d'A.Stepanov sur ses choix de design pour la STL.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  10. #10
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 064
    Points : 1 053
    Points
    1 053
    Par défaut
    Citation Envoyé par Alp Voir le message
    Pour ma part, je pense juste que les auteurs de bibliothèques de Boost ont su réfléchir à quand il est vraiment nécessaire de créer une hiérarchie de classes ou alors quand il fallait simplement faire une fonction libre surchargées/spécialisée, ce genre de choses... Le code de Boost est probablement celui qui exploite le mieux les possibilités du C++ actuel... et ce sera aussi le cas pour C++0x à mon avis.
    Pour ma part, j'en ai très rarement besoin de hiérarchies de classes, et étant principalement programmeur Java je peux vous dire que ni les concepteurs de Sun ni la plupart des créateurs de biblios ne les utilisent bien souvent. Par contre les hiérarchies d'interfaces sont, elles, très fréquentes.
    Du coté de Boost, la majeure partie des projets contiennent une grosse partie "concepts". Les hiérarchies de concepts y sont bien plus présentes que dans n'importe quelle autre bibliothèque, et on ne peut nier que les concepts sont à la méta-programmation ce que les interfaces sont à la POO.
    Au fond la conception est dans beaucoup de cas très similaire à celle qui aurait été choisie dans un langage pur objet, mais exprimée avec de la méta-programmation.

  11. #11
    Alp
    Alp est déconnecté
    Expert éminent sénior

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    Tout à fait. Par "hiérarchie de classes", j'incluais aussi les "interfaces", désolé de m'être mal exprimé.

    Et effectivement il y a bel et bien une analogie, il faut juste s'habituer au "metaprogramming way of design".

  12. #12
    Membre éclairé Avatar de HanLee
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    738
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2004
    Messages : 738
    Points : 871
    Points
    871
    Par défaut
    Vous la mettez où votre limite entre programmation générique et la métaprogrammation ?

    Boost c'est surtout de la programmation générique, combiné à de la métaprogrammation pour soit palier à des limitations du C++, ou soit pour avoir une programmation générique encore plus expressive, via les traits, et tout.

    Mais en OCaml, il n'y a pas de méta programmation dans la distribution officielle par exemple, le polymorphisme paramétrique est très bien géré (c'est un truc un peu plus sophistiqué que les generics je précise), le typage est parfait, mais il n'y a pas de génération de code comme en C++.

Discussions similaires

  1. Vos critiques de livres informatique
    Par Community Management dans le forum Evolutions du club
    Réponses: 117
    Dernier message: 22/04/2014, 12h16
  2. [FLASH MX] Lecture à l'envers
    Par Mouf dans le forum ActionScript 1 & ActionScript 2
    Réponses: 9
    Dernier message: 30/04/2006, 00h04
  3. jouer une animation a l'envers
    Par sylvain_bos dans le forum DirectX
    Réponses: 2
    Dernier message: 18/05/2004, 21h32
  4. unicité de champ les uns envers les autres
    Par Jovial dans le forum SQL Procédural
    Réponses: 6
    Dernier message: 16/04/2004, 08h34

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