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 :

Union et son usage


Sujet :

C

  1. #21
    Membre éclairé Avatar de dafpp
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2008
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2008
    Messages : 345
    Par défaut
    Pas d'adresse, tu veux dire quoi par là ? j'arrive à lire la donnée sans difficultée.

  2. #22
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 840
    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 840
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par anacharsis Voir le message
    salut !

    désolé de te contredire,
    Moi pareil

    Citation Envoyé par anacharsis Voir le message
    le seul interêt des unions, c'est le fait que les champs se recouvrent.
    Jusque là je suis d'accord.

    Citation Envoyé par anacharsis Voir le message
    on a la garantie que tous les champs commencent à la même adresse (absence d'octet de remplissage avant un quelconque des champs de l'union).
    Là pareil

    Citation Envoyé par anacharsis Voir le message
    on peut parfaitement accéder à tous les champs, tout le temps.
    Là (désolé de te contredire) mais non. Dans un union (comme cet exemple)
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    union {
        int x;
        long y;
    } toto;

    Tu peux remplir toto.x puis lire toto.x. Puis remplir toto.y puis lire toto.y. Mais tu ne peux pas remplir toto.x et lire toto.y, cela amène un comportement non garanti donc indéterminé...
    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]

  3. #23
    Membre éclairé Avatar de dafpp
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2008
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2008
    Messages : 345
    Par défaut
    En tant que tel on peut, le résultat sera juste faux.

    Je n'ai toujours pas eu mes réponses !!

  4. #24
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 840
    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 840
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par dafpp Voir le message
    En tant que tel on peut, le résultat sera juste faux.
    Non même pas. Oui si on le fait quand-même le résultat sera faux mais on n'a pas le droit de lire le membre de l'union qui n'est pas le dernier a avoir été écrit (http://www.developpez.net/forums/d70...s/#post4129693; http://www.developpez.net/forums/d83...s/#post4757449).
    Tout comme aller taper dans tab[5] quand tab est défini comme char[5]. On peut écrire l'instruction, on a 99,9% de chances que ça ne plante pas et avoir un résultat mais c'est interdit par la norme.
    Il ne faut pas confondre "taper un code qui compile" et "avoir le droit de le taper"...

    Citation Envoyé par dafpp Voir le message
    Je n'ai toujours pas eu mes réponses !!
    Bah tu en as eu pas mal. On t'a donné des pistes et des billes...
    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. #25
    Membre éclairé Avatar de dafpp
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2008
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2008
    Messages : 345
    Par défaut
    C'est bien vrai, mais je pensais qu'il y avait d'autre solution, mais l'union est pas vraiment bien pour faire ce que je souhaite.
    Je vais tenter de trouver un stratagème pour mes histoires de char.

  6. #26
    Membre chevronné
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2012
    Messages
    190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Janvier 2012
    Messages : 190
    Par défaut
    tu devrais insister, car ça marche
    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
    #include <stdio.h>
    typedef union{
    	unsigned char a;
    	unsigned short b;
    	unsigned int c;
    } uni_t;
    void dump(unsigned char * p){//écrit les 4 octets de l'union en hexa
    	int i;
    	for(i = 0; i < 4; i++)
    		printf("%02X ", p[i]);
    	puts("");
    }
    void main(void){
    	uni_t u;
    	printf("u size=%d address=%p\n", sizeof(u), &u);
    	printf("a size=%d address=%p\n", sizeof(u.a), &u.a);
    	printf("b size=%d address=%p\n", sizeof(u.b), &u.b);
    	printf("c size=%d address=%p\n", sizeof(u.c), &u.c);
    	puts("FF FF FF FF dans u en écrivant c");
    	u.c = -1;
    	dump(&u);
    	puts("00 00 FF FF dans u en ecrivant b");
    	u.b = 0;
    	dump(&u);
    	puts("FF 00 FF FF dans u en ecrivant a");
    	u.a = -1;
    	dump(&u.c);
    	puts("remarquez que j'ai lu u.c alors que je viens d'ecrire u.a");
    }
    il suffit juste de savoir ce qu'on veut faire.

    A+

  7. #27
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Sur le sujet de lecture/ecriture des membres d'une union, consultez la discussion suivante Recopier 4 char dans un float

    Les solutions proposées dans cette discussion peuvent d'ailleurs inspirer dafpp

  8. #28
    Membre éclairé Avatar de dafpp
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2008
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2008
    Messages : 345
    Par défaut
    Je vois un peu plus clair, mais sans doute parce que je ne code pas, et j'essaie d’abord de visualiser la chose, mais je ne vois pas comment je vais échapper aux char et de devoir enregistrer la taille de la chaine, à moins de faire - car les int me permettait de lire de traiter les 4-2 octets sans soucis:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    struct
    {
    	union
    	{
    		char data[32];
    		struct
    		{
    			char d1[20];
    			char d2[2];
    		...
    		} k;
    	} motif;
    	int * tab; //tableau des tailles de chaque types de "struct union struct", étant donné que je ne peux pas assurer d'avoir un \o dans les parties fixes des char, et que je ne suis pas sûr que ça n'arrivera qu'un fois ce problèmes.
    }

  9. #29
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Non même pas. Oui si on le fait quand-même le résultat sera faux mais on n'a pas le droit de lire le membre de l'union qui n'est pas le dernier a avoir été écrit (http://www.developpez.net/forums/d70...s/#post4129693; http://www.developpez.net/forums/d83...s/#post4757449).
    J'avoue que je ne savais pas..

    Cependant, je trouve la formulation mauvaise :

    puisque les variables démarrent à la même adresse, c'est simplement que les -définis par le type de x - n bytes (ou bits) sont écrits.

    Lire / se référer à une variable de type <= au type de x est donc possible : les bits ont été assignés (même si la valeur est incohrente)

    Et je dirais plus : si la valeur la plus grande de l'union a été assignée une fois, ou l'union a été créée via un calloc (et pas un malloc), cela devrait marcher, même si les valeurs sont incohérentes, tous les bits ont été assignés...


    Cela revient un peu à l'exemple que je donnais dans l'autre discussion à propos de l'instruction EQUIVALLENCE en Fortran.....


    Me trompe-je ???

  10. #30
    Membre chevronné
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2012
    Messages
    190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Janvier 2012
    Messages : 190
    Par défaut @dafpp
    deux point dans ton dernier code.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	int * tab; //tableau des tailles de chaque types de "struct union struct", étant donné que je ne peux pas assurer d'avoir un \o dans les parties fixes des char, et que je ne suis pas sûr que ça n'arrivera qu'un fois ce problèmes.
    ne déclare pas un tableau, seulement un pointeur.
    ce tableau ne serait pas très utile dans l'état actuel du programme. tu n'as pas besoin de te souvenir des tailles de d1, d2, ... car le compilateur s'en souvient
    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
    #include <stdio.h>
    struct stru_t
    {
    	union uni_t
    	{
    		char data[32];
    		struct stru_k
    		{
    			char d1[20];
    			char d2[2];
    			char d3[10];
    		} k;
    	} motif;
    	int * tab; //tableau des tailles de chaque types de "struct union struct", étant donné que je ne peux pas assurer d'avoir un \o dans les parties fixes des char, et que je ne suis pas sûr que ça n'arrivera qu'un fois ce problèmes.
    } s = {
    				{
    					{'a', 'z', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', 'q',
    						's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'w', 'x',
    						'c', 'v', 'b', 'n', '1', '2', '3', '4', '5', '6'
    					}
    				},
    				{
    					NULL
    				}
    			};
    void main(void){
    	int i;
    	for (i = 0; i < sizeof(s.motif.k.d1); i++)
    	  putch(s.motif.k.d1[i]);
    	 puts("");
    	for (i = 0; i < sizeof(s.motif.k.d2); i++)
    	  putch(s.motif.k.d2[i]);
    	 puts("");
    }
    A+

  11. #31
    Membre éclairé Avatar de dafpp
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2008
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2008
    Messages : 345
    Par défaut
    Oui tu fais bien de le préciser, mais vu que c'était une déclaration, je ne pouvais pas remplir le tableau directment, donc je me suis arreté à là.

  12. #32
    Membre chevronné
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2012
    Messages
    190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Janvier 2012
    Messages : 190
    Par défaut @ tous ceux qui ne veulent pas lire un champ qui n'est pas le dernier écrit
    extrait du draft de C99 dont je dispose.
    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
    ISO/IEC 9899:TC3 Committee Draft — Septermber 7, 2007 WG14/N1256
    8 EXAMPLE 3 The following is a valid fragment:
    union
    {
       struct 
       {
          int alltypes;
       } n;
       struct 
      {
         int type;
         int intnode;
       } ni;
       struct 
      {
         int type;
         double doublenode;
       } nf;
    } u;
    
    u.nf.type = 1;
    u.nf.doublenode = 3.14;
    /* ... */
    if (u.n.alltypes == 1)
    if (sin(u.nf.doublenode) == 0.0)
    /* ... */
    A+

  13. #33
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    je ne vois pas comment cela peut être implanté à part avoir des vraies variables différentes, présentées comme une union mais étant réellement une structure..

    Et dans ce cas on perd un des grands avantages de l'union qui est le gain de place mémoire..

    pour n'en garder qu'un qui est la flexibilité d'écriture..

    De mon point de vue c'est un retour en arrière et une perte sèche..


    Note: ici c'est bien une structure... je ne vois pas pourquoi tu as cité ça, c'est tellement largement utilisé que ça ne rentre pas dans le cas du débat, si ??? et ça ne date pas de C99... cela a toujours été possible..

    Par contre, si l'union reste ce qu'elle est, alors ce me semble ma remarque du post précédent reste valable

    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    typedef union _pu {
       char *s ;
       char c ;
       int i ;
       double d ;
    } u ;
     
    u myu ;
     
    myu.i = 0 ;

    dans ce cas, myu.c devrait être égal à 0, et myu.s à NULL (si NULL est bien défini comme 0x0), non ?

  14. #34
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par diogene Voir le message
    Sur le sujet de lecture/ecriture des membres d'une union, consultez la discussion suivante Recopier 4 char dans un float
    J'allais répéter mais je vois que j'ai déjà tout dit dans cette discussion.

  15. #35
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    typedef union _pu {
       char *s ;
       char c ;
       int i ;
       double d ;
    } u ;
     
    u myu ;
     
    myu.i = 0 ;

    dans ce cas, myu.c devrait être égal à 0
    Sauf dans le cas tordu où les int ont des bits de padding. J'ai déjà entendu parler d'architectures anciennes où c'est le cas, mais on ne m'a jamais confirmé qu'il y a jamais eu une implémentation du C pour ces machines.

    et myu.s à NULL (si NULL est bien défini comme 0x0), non?
    La constante entière 0, éventuellement castée en void*, est utilisée comme valeur pour NULL, mais la représentation physique peut être différente (et c'est un peu plus courant que le cas précédant, j'ai déjà entendu des rumeurs d'implémentations l'ayant fait). En prime, rien ne garanti que sizeof(myu.s) == sizeof(myu.i) (p.e. les implémentations sur 64 bits sont généralement des pointeurs sur 64 bits et des entiers sur 32).

    C'est comme pour les flottants, la valeur entière 0 -- et toutes les autres dans le cas des flottants -- peut être utilisées dans les contextes où il faut un flottant, la représentation utilisée ne sera pas nécessairement la même que celle de l'entier 0. Donc même si sizeof(myu.d) == sizeof(myu.i) (ce qui est rare), tu ne peux rien déduire de la valeur de myu.d.

  16. #36
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    ok.

    J'avais bien conscience pour les flottants, mais je pensais que pour les entiers, avec 0 ça marchait..

    'fin bref, en général dans les unions on siat quel membre on utilise..

    Sauf pour le cas du thread, auquel cas sans doute un champ de bits ou une analyse de bits convient miuex, je pense..



    Merci des liens, je m'endormirais moins bête ce soir (quoique..)

  17. #37
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Citation Envoyé par anacharsis Voir le message
    extrait du draft de C99 dont je dispose.
    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
    ISO/IEC 9899:TC3 Committee Draft — Septermber 7, 2007 WG14/N1256
    8 EXAMPLE 3 The following is a valid fragment:
    union
    {
       struct 
       {
          int alltypes;
       } n;
       struct 
      {
         int type;
         int intnode;
       } ni;
       struct 
      {
         int type;
         double doublenode;
       } nf;
    } u;
    
    u.nf.type = 1;
    u.nf.doublenode = 3.14;
    /* ... */
    if (u.n.alltypes == 1)
    if (sin(u.nf.doublenode) == 0.0)
    /* ... */
    A+
    Ce type de code constitue une exception, comme explicité ici, car les structures partagent une structure initiale commune:

    Citation Envoyé par n1256 §6.5.2.3
    One special guarantee is made in order to simplify the use of unions: if a union contains several structures that share a common initial sequence (see below), and if the union object currently contains one of these structures, it is permitted to inspect the common initial part of any of them anywhere that a declaration of the complete type of the union is visible. Two structures share a common initial sequence if corresponding members have compatible types (and, for bit-fields, the same widths) for a sequence of one or more initial members.
    C'est le seul cas prévu par la norme où il est possible d'accéder à la donnée stockée dans une union par un champ différent de celui utiliser pour initialiser cette dernière. Cette exception est toutefois limitée à la séquence commune des deux structures.

    Avec mes meilleures salutations

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  18. #38
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Thierry Chappuis Voir le message
    Ce type de code constitue une exception, comme explicité ici, car les structures partagent une structure initiale commune:

    exception, exception... t'y vas fort..

    Toute la programmation événementielle en C repose dessus : tout le code de X11 (depuis 1984)...

    Et dès q'on veut faire des fonctions enregistrées, (style callbacks) on utilise ce genre de mécanismes et de recouvrement...

  19. #39
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par Thierry Chappuis Voir le message
    C'est le seul cas prévu par la norme où il est possible d'accéder à la donnée stockée dans une union par un champ différent de celui utiliser pour initialiser cette dernière. Cette exception est toutefois limitée à la séquence commune des deux structures.
    C'est dépendant de l'implémentation et a le même effet qu'un memcpy. Voir
    http://www.open-std.org/JTC1/SC22/WG...ocs/dr_283.htm pour une clarification du texte de C99.

  20. #40
    Membre éclairé Avatar de dafpp
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2008
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2008
    Messages : 345
    Par défaut
    Bon j'ai rusé j'ai mis des '\0' en fin de chaine, je ne peux pas le faire pour toutes, mais c'est déjà ça, je ferai une copie d'octets à taille fixe pour gérer les parties où je ne peux pas faire comme j'ai dis juste avant.

    Merci à tous.

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. Réponses: 0
    Dernier message: 13/03/2015, 09h21
  2. Réponses: 8
    Dernier message: 23/01/2015, 16h26
  3. Réponses: 0
    Dernier message: 09/12/2013, 03h22
  4. Réponses: 0
    Dernier message: 13/04/2011, 15h10
  5. Traduction des Union C/C++ vers Delphi (usage DLL)
    Par Crafton dans le forum Langage
    Réponses: 6
    Dernier message: 22/02/2006, 08h56

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