Pas d'adresse, tu veux dire quoi par là ? j'arrive à lire la donnée sans difficultée.
Version imprimable
Pas d'adresse, tu veux dire quoi par là ? j'arrive à lire la donnée sans difficultée.
Moi pareil :mrgreen:
Jusque là je suis d'accord.
Là pareil
Là (désolé de te contredire) mais non. Dans un union (comme cet exemple)
Code:
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é...
En tant que tel on peut, le résultat sera juste faux.
Je n'ai toujours pas eu mes réponses !! :cry::cry:
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"...
Bah tu en as eu pas mal. On t'a donné des pistes et des billes...
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.
tu devrais insister, car ça marche
il suffit juste de savoir ce qu'on veut faire.Code:
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"); }
A+
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
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:
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. }
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 ???
deux point dans ton dernier code.ne déclare pas un tableau, seulement un pointeur.Code: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.
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 souvientA+Code:
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(""); }
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à.
extrait du draft de C99 dont je dispose.
A+Code:
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) /* ... */
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: :oops: 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:
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 ?
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.
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).Citation:
et myu.s à NULL (si NULL est bien défini comme 0x0), non?
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.
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 :aie: (quoique..;))
Ce type de code constitue une exception, comme explicité ici, car les structures partagent une structure initiale commune:
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.Citation:
Envoyé par n1256 §6.5.2.3
Avec mes meilleures salutations
Thierry
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.
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.