char[] ou byte[] ? - C - Programmation
Marsh Posté le 11-04-2009 à 12:31:03
char n'est pas toujours signé, ça dépend de l'implémentation. Certains compilateurs laissent le programmeur choisir, avec un paramètre de compilation.
Tu peux, et surtout en C, copier un char, un signed char (ça existe !) et un unsigned char de l'un vers l'autre, ça sera une copie bit-à-bit sans aucune perte d'information.
Code :
|
Donc pour répondre à ta question, tu peux sans problème stocker des char dans des unsigned char et vice-versa, pas de problème.
Note tout de même que ces 3 types sont différents et requierent, si on veut faire une syntaxe propre, un cast.
Pour l'annectode, en C++ passer de char à unsigned char demande un reinterpret_cast et non pas un static_cast, même si les compilateurs sont assez tolérants là dessus.
Marsh Posté le 11-04-2009 à 13:41:10
jesus_christ a écrit : Donc pour répondre à ta question, tu peux sans problème stocker des char dans des unsigned char et vice-versa, pas de problème. |
En théorie il y a possibilité de cas problèmatique (signed char peut avoir une représentation "trap", un -0 en complément à un; je parie que si une implémentation doit utiliser cette possibilité, elle va avoir char qui est non signé).
Citation : Note tout de même que ces 3 types sont différents et requierent, si on veut faire une syntaxe propre, un cast. |
Par "syntaxe propre" entends-tu quelque chose d'autre que "le style que je préfère"?
Citation : Pour l'annectode, en C++ passer de char à unsigned char demande un reinterpret_cast et non pas un static_cast, même si les compilateurs sont assez tolérants là dessus. |
J'aimerais bien avoir ton raisonnement (reinterpret_cast n'est autorisé qu'avec des pointeurs et des références, le cas des références étant défini a partir du cas des pointeurs). Donc d'après moi, un compilateur C++ doit donner une erreur sur
Code :
|
(petite vérification, c'est le cas de tous ceux que j'ai sous la main: g++, sun CC, Intel icpc, Como).
Marsh Posté le 11-04-2009 à 15:06:05
Un Programmeur a écrit :
|
Oui oui c'est ça, dans mon exemple avec le memcpy, qui serait devenu un std::copy, c'est le pointeur aurait du être reinterpret_casté.
Marsh Posté le 11-04-2009 à 16:47:16
jesus_christ a écrit : |
Ok donc ça devrait aller. Par contre, pour les opérations de manipulation de bits, ça sera une autre histoire.
Marsh Posté le 11-04-2009 à 16:55:31
oui, typiquement les shifts se comportent différement selon le signness.
Pour un masque ^, | ou & (xor, or ou and) normalement il n'y a pas de différence, sauf si ton architecture est un peu spéciale.
Par contre pour du stockage, à plus forte raison avec des memcpy, tu ne devrais pas avoir de pb.
Marsh Posté le 11-04-2009 à 21:36:46
jesus_christ a écrit : Pour l'annectode, en C++ passer de char à unsigned char demande un reinterpret_cast et non pas un static_cast, même si les compilateurs sont assez tolérants là dessus. |
jesus_christ a écrit : Oui oui c'est ça, dans mon exemple avec le memcpy, qui serait devenu un std::copy, c'est le pointeur aurait du être reinterpret_casté. |
C'est lesquels tes compilateurs qui acceptent un static_cast pour passer d'un char* à un unsigned char*? Tous ceux que j'ai sous la main génèrent une erreur dans leur mode par défaut .
Marsh Posté le 14-04-2009 à 10:43:37
Emmanuel Delahaye a écrit : |
Quel est ton raisonnement? Je viens de relire 6.2.6.2 et rien ne m'y fait changer d'avis:
- unsigned char n'a pas de trap-representation ni de bits de padding
- signed char n'a pas de bits de padding et peut avoir une trap representation (la seule est celle qui correspondrait a un -0 en grandeur et signe ou en complement a un; l'absence de bits de padding previent l'existance d'autres)
- les autres types entiers peuvent avoir les deux qu'ils soient signes ou non.
Il y a peut-etre une contrainte ailleurs qui empeche -0 d'etre une trap value, mais je ne l'ai pas vue.
Marsh Posté le 14-04-2009 à 10:52:54
Un Programmeur a écrit : |
OK, j'avais oublié ça.
Marsh Posté le 14-04-2009 à 11:24:15
ReplyMarsh Posté le 14-04-2009 à 11:59:56
Joel F a écrit : concretement, ca peut induire quelle genre d'erreur ces histoires ? |
Concretement? Je doute que tu vas trouver une machine en complement a un ou en grandeur et signe (c'est pour cela
que j'ai commence par "en theorie"; je ne passerais pas un quart de seconde a m'occuper du cas dans un programme),
meme dans l'embarque.
OK, il y a les descendants des Univac 1100 qui etaient toujours vendu par Unisys la derniere fois que j'ai regarde --
mais ca m'etonnerait qu'ils soient programmes en C et ca ne m'etonnerait pas qu'ils aient fait faillite depuis. Une autre
possibilite, c'est l'utilisation d'un format commun flottant/entier -- voir les descendants des B6500 chez l'autre ancetre
d'Unisys -- mais cette architecture cadre tres mal avec toutes les contraintes explicites du C, sans compter
les us et coutumes, je serais curieux de voir un compilateur C conforme pour une quelconque de ces deux architectures
et comment il s'integre avec le reste du systeme, meme s'il est toujours possible de se les procurer chez Unisys. Et a part
les necessites de compatibilite avec le passe, je ne vois pas de bonnes raisons de ne pas faire du complement a 2 pour
les entiers, et je vois un tas de bonnes raisons pour le faire.
Marsh Posté le 14-04-2009 à 13:22:25
Je pose la question car j'utilise ~0 et autres trucvs du meme style dans ma bibliothqèue de calcul numerique et je me demandait si ca cachait aps des loups. Comme je supporte que les archi/compilos post-modernes, ca devrait aller.
Marsh Posté le 14-04-2009 à 14:55:41
Joel F a écrit : Je pose la question car j'utilise ~0 et autres trucvs du meme style dans ma bibliothqèue de calcul numerique et je me demandait si ca cachait aps des loups. Comme je supporte que les archi/compilos post-modernes, ca devrait aller. |
~0 ? J'utiliserais -1 ou ~0U suivant le contexte, mais en general je prefere reserver les manipulations de bits aux unsigned; les utiliser avec des signed a des possibilites de problemes un peu plus nombreuses que simplement celles dues aux representations etranges (en particulier avec les decalages).
Marsh Posté le 14-04-2009 à 15:22:52
en fait j'utilise ~0 comme manière géénrique de renvoyait un entier de taille qqconque avec tt les bits à un au lieu d'enumérer 0xFF, 0xFFFF etc
Marsh Posté le 14-04-2009 à 15:37:51
Joel F a écrit : en fait j'utilise ~0 comme manière géénrique de renvoyait un entier de taille qqconque avec tt les bits à un au lieu d'enumérer 0xFF, 0xFFFF etc |
La méthode officielle est ((T)-1)
T étant le type.
Marsh Posté le 14-04-2009 à 15:52:10
Si je m'interesse a la representation (ce que "tous les bits a un" me laisse croire), j'utilise des unsigned. Donc ~0U, ~0UL, ~0ULL.
Marsh Posté le 14-04-2009 à 15:56:53
Emmanuel Delahaye a écrit : |
Pour un type non signe, ~0U a le meme resultat et je vais utiliser l'un ou l'autre suivant le contexte (c'est pour faire en sorte que le +1 amene a 0, j'utilise -1U, si je pense aux bits, j'utilise ~0U). Et pour un type signe, ta methode ne va pas avoir le bon motif de bits dans les cas rares de representations grandeur et signe (ou il faudrait utiliser -MAX_INT) et complement a un (ou il faudrait utiliser -0) tandis que ~0 va l'avoir.
Marsh Posté le 11-04-2009 à 11:32:28
Salut,
Pour un projet C embarqué, j'ai développé une petite lib bien utile que nous utilisons de façon extensive.
Parmi les choses développées, il y a une structure String (chaîne de caractères extensible et sûre), et petite structure destinée à servir de buffer d'octets extensible, nommée Arrchar définie ainsi:
(Incidemment, les structures Arrchar et String sont structurellement identiques, mais les fonctions qui agissent dessus diffèrent)
Sur cette structure, j'ai défini un certains nombre de "méthodes", de mémoire:
Le problème est que je me rends compte que j'ai bien loosé en choisissant le type char pour buf, qui est signé.
Ma question, en pratique les buffers d'octets utilisés la plupart du temps dans les applis embarquées, ce sont des signés ou des non signés ?
(heureusement, je n'ai pas encore écrit des trucs du style arrchartoBCD)
Y'aurait-il une ruse pour pouvoir utiliser les deux types avec la même structure ou dois-je écrire une "classe" Arrbyte ?
Message édité par el muchacho le 11-04-2009 à 11:37:43
---------------
Les aéroports où il fait bon attendre, voila un topic qu'il est bien