Aurais-tu une référence ?
Version imprimable
Je ne lis pas la même chose que toi dans cette liste (mais je ne suis pas un expert du standardese, je peux très bien me planter) :
Telle que je lis la liste, on peut écrire :Code:
1
2
3
4
5
6
7
8 union U { unsigned char c; float f; }; U u; u.f = 3.14;
Mais le code suivant reste indéfini :Code:
1
2 unsigned char*s = reinterpret_cast<unsigned char*>(&u); cout << s[0];
Code:cout << u.c;
@JolyLoic : Si une union U a 2 membre (n de type N et m de type M) et que c'est n qui est actif, alors l'expression u.m (u de type U) n'est pas une lvalue de type M ?
Pour moi, c'est effectivement une lvalue de type M, mais qu'on n'a pas le droit de convertir en prvalue. Je ne trouve aucun texte pour corroborer ce point de vue, et en particulier pour définir précisément ce que signifie "actif".
Si c'est bien un lvalue alors je serais plutôt de l'avis de Goten, ce n'est pas un UB car on accède à un objet via une lvalue de type char, c'est ce que je comprend du passage cité par Goten.
Pour le actif, c'est dans la définition que la norme (n3290) fait d'une union, mais à part les paragraphes sur les unions ce n'est pas détaillé ailleurs.
Re-Bonjour, soit on s'écarte du sujet, soit je n'arrive plus à suivre la discussion ^^. Du coup, je ne sais pas trop quelle méthode employer... Il faudrait peut être que je fasse un code qui réalise la conversion pas à pas des octets en float (calcul de la mantisse, etc...), mais ça sera peut être plus long à l'éxécution... :(
Dailleurs le problème maintenant est que plusieurs méthodes fonctionnent mais j'obtiens toujours des valeurs arrondies...
EDIT : Bon tout fonctionnne, même au niveau de la précision :
Merci à tous en tout cas :)Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 unsigned char result[4]; float * f; float flt; if(cpu_type==2){ result[0] = getOctet(fichierstdf); result[1] = getOctet(fichierstdf); result[2] = getOctet(fichierstdf); result[3] = getOctet(fichierstdf); }else{ result[3] = getOctet(fichierstdf); result[2] = getOctet(fichierstdf); result[1] = getOctet(fichierstdf); result[0] = getOctet(fichierstdf);} //f=(float *)result; //flt =*f; fonctionne aussi memcpy(&flt, &result,sizeof(float)); return flt;
J'ai posté sur les mailing lists du comité de normalisation, et j'ai eu une réponse de Jens Maurer, qui est d'accord avec ton interprétation, même s'il est prudent dans son accord. Je le cite :. Il suggère aussi de lire les core issues 1116 et 636. Avec le réordonnancement proposé par 1116, je deviens moi aussi d'accord.Citation:
It seems to me that the exception for "unsigned char" does apply, thus the above is not undefined behavior. However, the value you get for "u.c" is unspecified, except that (I think) you can expect it to remain stable until you modify "u" next.
Mais tout ça me conforte que dans la mesure du possible, j'éviterais d'utiliser des unions dans du code que j'écris, c'est bien trop casse gueule :)
Eames38 : Ce que tu peux retenir de notre chipotage c'est que la conversion à base d'union n'est pas garantie de fonctionner, surtout dans le sens char[] => float.