Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1401 connectés 

  FORUM HardWare.fr
  Programmation
  C

  char[] ou byte[] ?

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

char[] ou byte[] ?

n°1872225
el muchach​o
Comfortably Numb
Posté le 11-04-2009 à 11:32:28  profilanswer
 

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:

Code :
  1. typedef struct Arrchar{
  2.    size_t len;
  3.    size_t sz;
  4.    char *buf;
  5. };


(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:

Code :
  1. size_t arrcharcpy(Arrchar *dst, const Arrchar *src);
  2. size_t arrcharcat(Arrchar *dst, const Arrchar *src);
  3. size_t arrcharfill(Arrchar *ac, const char c);
  4. String * arrchartostring(const Arrchar *ac, const FORMAT f, const char separator); // FORMAT peut être HEXA, OCTO, DEC ou ASCII
  5. void arrcharleft(Arrchar *ac, const char c); // déplace le contenu à gauche
  6. void arrcharright(Arrchar *ac, const char c); // déplace le contenu à droite
  7. char arrcharpop (Arrchar *ac);
  8. void arrcharpush (Arrchar *ac, const char c);
  9. ...
  10. etc
 

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
mood
Publicité
Posté le 11-04-2009 à 11:32:28  profilanswer
 

n°1872234
jesus_chri​st
votre nouveau dieu
Posté le 11-04-2009 à 12:31:03  profilanswer
 

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 :
  1. char* c = malloc( 42 );
  2. signed char* sc = malloc( 42 );
  3. unsigned char* uc = malloc( 42 );
  4. memcpy( c, uc, 42 );
  5. memcpy( sc, c, 42 );
  6. memcpy( uc, sc, 42 );
  7. /*ou plus simplement :*/
  8. char x = 'a';
  9. unsigned char y;
  10. y = (unsigned char)x;
  11. x = (char)y;
  12. printf( "%c", x ); // a
  13. /* toutes ces copies de qlqchose-char sont indolores et ne modifient pas les valeurs selon le signe */


 
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.

n°1872247
Un Program​meur
Posté le 11-04-2009 à 13:41:10  profilanswer
 

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 :
  1. unsigned char f(char c)
  2. {
  3.    return reinterpret_cast<unsigned char>(c);
  4. }


(petite vérification, c'est le cas de tous ceux que j'ai sous la main: g++, sun CC, Intel icpc, Como).

n°1872253
jesus_chri​st
votre nouveau dieu
Posté le 11-04-2009 à 15:06:05  profilanswer
 

Un Programmeur a écrit :


 
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é).
 
Bonne remarque, mon explication impose que la machine utilise le complément à 2, ce qui est le cas d'à peu près toutes les machines à peu près actuelles, même si dans l'embarqué, ce qui est le cas ici, on peut tomber sur des archi exotiques.
 

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"?
 
Une syntaxe qui ne sort pas de warning même à un niveau de warning élevé on va dire. Et keep cool, t'es pas obligé de poser la question sur un ton si hautin.
 

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).  [...]


 
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é.

n°1872261
el muchach​o
Comfortably Numb
Posté le 11-04-2009 à 16:47:16  profilanswer
 

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.
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.


Ok donc ça devrait aller. Par contre, pour les opérations de manipulation de bits, ça sera une autre histoire.

n°1872263
jesus_chri​st
votre nouveau dieu
Posté le 11-04-2009 à 16:55:31  profilanswer
 

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.

n°1872280
Un Program​meur
Posté le 11-04-2009 à 21:36:46  profilanswer
 

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 .

n°1872655
Un Program​meur
Posté le 14-04-2009 à 10:43:37  profilanswer
 

Emmanuel Delahaye a écrit :


Non. Il n'y a pas de trap-representation sur un char (signé ou non). Ca commence à partir de short...


 
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.

n°1872662
Emmanuel D​elahaye
C is a sharp tool
Posté le 14-04-2009 à 10:52:54  profilanswer
 

Un Programmeur 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)


OK, j'avais oublié ça.
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
n°1872696
Joel F
Real men use unique_ptr
Posté le 14-04-2009 à 11:24:15  profilanswer
 

concretement, ca peut induire quelle genre d'erreur ces histoires ?

mood
Publicité
Posté le 14-04-2009 à 11:24:15  profilanswer
 

n°1872730
Un Program​meur
Posté le 14-04-2009 à 11:59:56  profilanswer
 

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.

n°1872769
Joel F
Real men use unique_ptr
Posté le 14-04-2009 à 13:22:25  profilanswer
 

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.

n°1872805
Un Program​meur
Posté le 14-04-2009 à 14:55:41  profilanswer
 

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).

n°1872832
Joel F
Real men use unique_ptr
Posté le 14-04-2009 à 15:22:52  profilanswer
 

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

n°1872840
Emmanuel D​elahaye
C is a sharp tool
Posté le 14-04-2009 à 15:37:51  profilanswer
 

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.

Message cité 1 fois
Message édité par Emmanuel Delahaye le 14-04-2009 à 15:38:09

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
n°1872844
Joel F
Real men use unique_ptr
Posté le 14-04-2009 à 15:42:27  profilanswer
 

je note

n°1872848
Un Program​meur
Posté le 14-04-2009 à 15:52:10  profilanswer
 

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.

n°1872852
Un Program​meur
Posté le 14-04-2009 à 15:56:53  profilanswer
 

Emmanuel Delahaye a écrit :


La méthode officielle est ((T)-1)
 
T étant le type.


 
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.


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  char[] ou byte[] ?

 

Sujets relatifs
PK sur deux champs en char [Linker error] undefined reference to `RngStream::RngStream(char con
[Résolu] TO_CHAR() en MSSQL ?Transformer jpg en octet : System.Drawing.Bitmap => Byte[]
Question sur le "type", INT, Char... ?Récupérer un nombre dans un char en c
difference entre u_char et char[résolu] fgets et imlib_load_image
impossible de convertir le paramètre 2 de 'const char *' en 'char *'[Réglé] ip:port en char traduire en decimal. master query
Plus de sujets relatifs à : char[] ou byte[] ?


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR