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 Delphi Discussion :

Question (probablement idiote) à propos du try/finally


Sujet :

Langage Delphi

  1. #1
    Membre éclairé Avatar de slimjoe
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Canada

    Informations forums :
    Inscription : Juin 2005
    Messages : 647
    Points : 789
    Points
    789
    Par défaut Question (probablement idiote) à propos du try/finally
    Bonjour,

    Je travaille avec Delphi depuis plusieurs années alors je me sens un peu con de poser ma question...

    J'ai testé les fonctions suivantes sous Delphi 7 et Delphi 2007 (projets Win32) et les résultats sont identiques.

    Question #1 : Pourquoi est-ce que la fonction ci-dessous me retourne 1 ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function MonTestInt: integer;
    begin
       try
          Result := 1;
          Exit;
       finally
          Result := 2;
       end;
     
       Result := 3;
    end;

    Question #2 : Si la fonction précédente me retourne 1, pourquoi est-ce que la fonction ci-dessous me retourne '2' (code semblable, mais avec des strings) ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function MonTestStr: string;
    begin
       try
          Result := '1';
          Exit;
       finally
          Result := '2';
       end;
     
       Result := '3';
    end;

    Question #3 (c'est ma vraie question ) : Pourquoi est-ce que le code suivant affiche l'avertissement « W1035 Return value of function 'MonTestInt' might be undefined » ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    function MonTestInt: integer;
    begin
       try
          Exit;
       finally
          Result := 2;
       end;
    end;
    Est-ce que je dois changer ma façon de travailler avec les try/finally ?

    Merci!
    -Slimjoe

  2. #2
    Membre expérimenté
    Homme Profil pro
    Ingenieur de recherche - Ecologue
    Inscrit en
    Juin 2003
    Messages
    1 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingenieur de recherche - Ecologue

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 146
    Points : 1 412
    Points
    1 412
    Par défaut
    #1
    Après result := 1, tu places un Exit.
    Donc tu sort de la fonction directement sans passer par la ligne result := 3.

    donc normal

    # 2

    c'est pas. Il ne suit pas le EXIT

    #3 normal
    tu sors de la fonction sans attribuer de valeur a la fonction..


    les problèmes ne sont pas dans le TRY... FINALLY, mais dans l'utilisation du EXIT.
    NB : sans le EXIT, tes 2 premieres reverront systématiquement 3.
    Merci d'ajouter un sur les tags qui vous ont aidé

  3. #3
    Membre éclairé Avatar de slimjoe
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Canada

    Informations forums :
    Inscription : Juin 2005
    Messages : 647
    Points : 789
    Points
    789
    Par défaut
    Citation Envoyé par dehorter olivier Voir le message
    #1
    Après result := 1, tu places un Exit.
    Donc tu sort de la fonction directement sans passer par la ligne result := 3.

    donc normal

    # 2

    c'est pas. Il ne suit pas le EXIT

    #3 normal
    tu sors de la fonction sans attribuer de valeur a la fonction..


    les problèmes ne sont pas dans le TRY... FINALLY, mais dans l'utilisation du EXIT.
    NB : sans le EXIT, tes 2 premieres reverront systématiquement 3.
    Bonjour et merci pour votre aide.

    J'aurais dû être plus clair : la valeur attendue pour les deux première fonctions est « 2 ». Ma question est : pourquoi est-ce que le premier exemple retourne « 1 » et le second « 2 » ? Pourquoi est-ce que les deux premiers exemples (très semblables) se comportent de façons différentes ?

    Selon l'aide de Delphi, il semblerait que les instructions du finally soient exécutées malgré la présence du exit. Désolé, c'est en anglais :

    Exit passes control away from the current procedure, not merely the current block. But Exit does not violate the flow of control dictated by a try..finally construct; if Exit is called inside the try clause, the finally clause is still executed.
    Est-ce qu'il y a quelque chose que je ne comprends pas ?

    Merci encore!
    -Slimjoe

  4. #4
    Membre expérimenté
    Homme Profil pro
    Ingenieur de recherche - Ecologue
    Inscrit en
    Juin 2003
    Messages
    1 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingenieur de recherche - Ecologue

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 146
    Points : 1 412
    Points
    1 412
    Par défaut
    non, tu as raison

    aide de delphi 2010
    Remarque : Exit fait passer le contrôle en dehors de la procédure en cours, pas seulement du bloc en cours. Mais Exit ne déroge pas du contrôle de flux dicté par une construction try..finally ; si Exit est appelée dans la clause try, la clause finally est encore exécutée.

    Et en enlevant le exit qui ne sert à rien (mais c'est peut etre une simplification dans une fonction plus complexe)

    la, je sèche aussi
    Merci d'ajouter un sur les tags qui vous ont aidé

  5. #5
    Membre éclairé Avatar de slimjoe
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Canada

    Informations forums :
    Inscription : Juin 2005
    Messages : 647
    Points : 789
    Points
    789
    Par défaut
    Citation Envoyé par dehorter olivier Voir le message
    Et en enlevant le exit qui ne sert à rien (mais c'est peut etre une simplification dans une fonction plus complexe)
    C'est malheureusement le cas . J'ai l'habitude de simplifier mes exemples au maximum pour éliminer les facteurs variables.

    Je crains sincèrement que Delphi bousille mes finally... J'aimerais beaucoup qu'on me démontre le contraire... Quelqu'un a une idée ?
    -Slimjoe

  6. #6
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 430
    Points
    28 430
    Par défaut
    C'est un joli bug lié à l'optimisation comme le montre le warning !
    Nom : bug.jpg
Affichages : 210
Taille : 22,3 Ko
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  7. #7
    Expert confirmé

    Profil pro
    Leader Technique
    Inscrit en
    Juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Leader Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 756
    Points : 4 170
    Points
    4 170
    Par défaut
    Celui là, il fallait le trouver

    Comme l'a indiqué Paul TOTH, du fait du result := 3 juste en dessous, l'optimiseur pense que le result := 2 ne sert à rien et élimine le code en question.

    Je viens de faire le test avec la fenêtre CPU, on voit bien qu'après le Exit, le finally est bien exécuté. Par contre, il n'y a aucun code généré pour l'affectation du résultat.

    Si on enlève le result := 3, le résultat est bien 2 !

    Ce qui est étonnant, c'est qu'on a le même résultat, même en désactivant les optimisations.

  8. #8
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 857
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 857
    Points : 11 291
    Points
    11 291
    Billets dans le blog
    6
    Par défaut
    Lazarus me dit 2 pour les codes #1 et #2 : ouf !

    Et ne met pas de warning pour le #3

    Maintenant, si on veut ergoter, le code qui suit le finally ne peut jamais s'exécuter (hormis Label et GoTo, pê) et n'a donc pas lieu d'y être...

    Pour qu'il s'exécute, il faut un code du type :

    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
    function MonTestStr(a: integer): string;
    begin
       try
        try
          if a<0
          then raise Exception.Create('négatif !')
          else Result := '1';
          Exit;
        except
          on E: Exception
          do ShowMessage(E.Message);
        end;
       finally
          Result := '2';
       end;
       Result := '3'; // si a <0 car l'exception saute le Exit !
    end;
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  9. #9
    Membre expérimenté Avatar de guillemouze
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    876
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Novembre 2004
    Messages : 876
    Points : 1 448
    Points
    1 448
    Par défaut
    c'est une vieille feinte (pour palier à un bug, il faut bien feinter), mais ce que je fais pour forcer a linker des fonctions pour utiliser dans l'evaluateur (sinon il compile pas les fonctions, le ) c'est un truc du genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    if IsZero(1) then //le compilateur ne voit pas que c'est tjrs false :)
    begin
      MaFonctionDeDebug();
    end;
    donc tu peut utiliser cette "technique" pour ton probleme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    function MonTestInt: integer;
    begin
       try
          Exit;
       finally
          Result := 2;
          if IsZero(Result) then sleep(0); //pour le forcer à utiliser le result et donc ne pas eliminer la ligne precedente
          //ou
          if IsZero(1) then Inc(Result); // celle la est valide si ton result peut valoir 0, mais celle d'avant ne fait pas non plus grand chose de plus
       end;
    end;

  10. #10
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 447
    Points : 24 849
    Points
    24 849
    Par défaut
    Bonne étude ! slimjoe !
    Je pense avoir eu une fois, un problème similaire avec un Result integer, avec un comportement illogique, comme le fait remarque Paul Toth, j'avais aussi un Avertissement !
    Hors je ne laisse jamais aucun Avertissement sans le comprendre et le corriger car cela indique souvent une erreur d'algo !
    J'ai modifié mon code de façon à ne plus avoir d'avertissement, il me semble que cela avait été une gymnastique comme celle proposé par tourlourou, déclenchement d'exception au lieu d'un code d'erreur !

    @tourlourou, le compilateur FreePascal Lazarus est donc moins buggé que celui de Delphi ! Hum !
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  11. #11
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 857
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 857
    Points : 11 291
    Points
    11 291
    Billets dans le blog
    6
    Par défaut
    @Shaï : moins de bugs pour le compilo dans Lazarus, je doute ; pour le debugger, je n'en ai malheureusement aucun (dans mon environnement)...

    mais ça ne fonctionne pas si mal

    mes plus gros problèmes viennent de mon ignorance et des difficultés de trouver les ressources pour les combler en FPC/Lazarus.

    je suis issu d'une culture livresque (derrière moi, 1m50 de livres sur une étagère) et j'ai un peu de mal à me contenter de tutos / exemples / posts pas toujours disponibles ou faciles à dénicher !

    mais 2 actualités pour moi :
    http://lazarus.developpez.com/index/...s-sur-Lazarus/
    et
    pour continuer de coder avec les pieds...
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  12. #12
    Membre éclairé Avatar de slimjoe
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Canada

    Informations forums :
    Inscription : Juin 2005
    Messages : 647
    Points : 789
    Points
    789
    Par défaut
    Bonjour à tous et merci pour votre aide.

    J'ai effectué des tests avec Delphi XE et il semble que le problème ait été corrigé. Je sais pas pour vous, mais moi ce genre de bug me terrorise... Je me mets soudainement à douter de tous mes try/finally...

    Merci encore!
    -Slimjoe

  13. #13
    Membre éclairé Avatar de slimjoe
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Canada

    Informations forums :
    Inscription : Juin 2005
    Messages : 647
    Points : 789
    Points
    789
    Par défaut
    Re-bonjour!

    Êtes-vous prêts pour un comportement encore plus étrange ? Le code suivant est fonctionnel et retourne 2 tel qu'attendu.

    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
    function MonTestInt: integer;
     
       procedure SetResult(const AResult: integer);
       begin
          //Cette procédure n'est jamais appelée
          Result := AResult;
       end;
     
    begin
       try
          Result := 1;
          Exit;
       finally
          Result := 2;
       end;
     
       Result := 3;
    end;
    J'étais à adapter le truc de guillemouze dans mon projet en me disant qu'au lieu de faire une procédure quelconque, je pourrais m'en servir pour affecter la valeur de retour quand je me suis rendu compte que je n'ai même pas besoin d'appeler ladite procédure. La déclarer suffit (en autant que j'affecte Result).

    -Slimjoe

  14. #14
    Membre expérimenté Avatar de guillemouze
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    876
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Novembre 2004
    Messages : 876
    Points : 1 448
    Points
    1 448
    Par défaut
    Etrange effectivement. Ce que je subodore, c'est que ce cas la est "trop complexe" pour qu'il puisse optimiser sans risquer de casser le comportement dans certaines situations.
    Et il ne les compile vraiement pas les lignes de ta procedure interne (pas de petit point bleu) ?

  15. #15
    Membre éclairé Avatar de slimjoe
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Canada

    Informations forums :
    Inscription : Juin 2005
    Messages : 647
    Points : 789
    Points
    789
    Par défaut
    Citation Envoyé par guillemouze Voir le message
    Et il ne les compile vraiement pas les lignes de ta procedure interne (pas de petit point bleu) ?
    Non, pas de point bleu :

    Nom : Capture.JPG
Affichages : 180
Taille : 48,8 Ko

    Sans la procédure :

    Nom : Capture2.JPG
Affichages : 158
Taille : 46,9 Ko
    -Slimjoe

  16. #16
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    707
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 707
    Points : 777
    Points
    777
    Par défaut
    Excusez-moi mais à l'origine, la fonction est mal codée, en toute logique il faudrait avoir...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function MonTestInt: integer;
    begin
      Result := 3;
      try
        Result := 1;
        Exit;
      finally
        Result := 2;
      end;
    end;
    C'est-à-dire initialiser Result avant de faire les traitements dans un try/finally qui peut comme son nom l'indique, foirer. Ou bien ?

  17. #17
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 685
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 685
    Points : 13 102
    Points
    13 102
    Par défaut
    Disons que le résultat n'est pas identique. Dans ton codage, Result vaudra toujours 2 alors que dans le premier cas, il vaudra 3 si la fonction échoue et 2 si elle réussi

  18. #18
    Membre éclairé Avatar de slimjoe
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Canada

    Informations forums :
    Inscription : Juin 2005
    Messages : 647
    Points : 789
    Points
    789
    Par défaut
    Citation Envoyé par GoustiFruit Voir le message
    Excusez-moi mais à l'origine, la fonction est mal codée, en toute logique il faudrait avoir...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function MonTestInt: integer;
    begin
      Result := 3;
      try
        Result := 1;
        Exit;
      finally
        Result := 2;
      end;
    end;
    C'est-à-dire initialiser Result avant de faire les traitements dans un try/finally qui peut comme son nom l'indique, foirer. Ou bien ?
    Citation Envoyé par Andnotor Voir le message
    Disons que le résultat n'est pas identique. Dans ton codage, Result vaudra toujours 2 alors que dans le premier cas, il vaudra 3 si la fonction échoue et 2 si elle réussi
    Dans mon exemple, « Result := 3; » ne sert effectivement à rien (la fonction ne retournera jamais 3). C'est juste que le bug ne semble survenir que si j'affecte « Result » après le « finally ».
    -Slimjoe

  19. #19
    Membre éprouvé
    Avatar de Montor
    Homme Profil pro
    Autre
    Inscrit en
    Avril 2008
    Messages
    879
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Avril 2008
    Messages : 879
    Points : 963
    Points
    963
    Par défaut
    Pour la troisièmement question c'est normal puisque une variable locale dans la section finally /end
    doit âtre initialisée avant l'exécution de try/finally
    dans l'excemple suivant montre la pertinence de cette démarche
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
       Result:= TFilestream.Create('fichierIntrouvable',fmOpenRead);
       try
     
       finally
          Result.Free
       end;
    Par contre le code suivant prdt une violation d'access
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
       try
            Result:= TFilestream.Create('fichierIntrouvable',fmOpenRead);
       finally
          Result.Free
       end;
    Voici une aurte situation ou le compilateur ne donne aucun avertissent concernant
    la valeur de retour
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    var L:integer = -1;
    function rrr():integer;
    begin
     for Result := 0 to L do
           if Result = 5  then
               break;
     
    end;

  20. #20
    Membre éclairé Avatar de slimjoe
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Canada

    Informations forums :
    Inscription : Juin 2005
    Messages : 647
    Points : 789
    Points
    789
    Par défaut
    Citation Envoyé par Montor Voir le message
    Pour la troisièmement question c'est normal puisque une variable locale dans la section finally /end
    doit âtre initialisée avant l'exécution de try/finally
    Ça fait du sens. Merci .
    -Slimjoe

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [D7]Problème Try Finally End
    Par delphi5user dans le forum Delphi
    Réponses: 12
    Dernier message: 17/04/2007, 16h37
  2. Réponses: 9
    Dernier message: 12/03/2007, 23h43
  3. Question technique a propos de httpd.conf
    Par arkheron dans le forum Apache
    Réponses: 3
    Dernier message: 19/06/2006, 12h42
  4. Des conséquences du try...finally
    Par fulster dans le forum Langage
    Réponses: 3
    Dernier message: 15/03/2006, 01h57
  5. [.NET] Une question technique a propos du mode asynchrone
    Par nicknolt dans le forum Général Dotnet
    Réponses: 4
    Dernier message: 08/06/2004, 10h07

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