56 votes

Un tampon d'octets doit-il être signé ou non signé ?

Un tampon d'octets doit-il être signé char ou unsigned char ou simplement un tampon char ? Y a-t-il des différences entre le C et le C++ ?

Gracias.

47voto

Si vous avez l'intention de stocker des données binaires arbitraires, vous devez utiliser la fonction unsigned char . C'est le seul type de données dont la norme C garantit l'absence de bits de remplissage. Tous les autres types de données peuvent contenir des bits de remplissage dans leur représentation objet (c'est-à-dire celle qui contient tous les bits d'un objet, au lieu de seulement ceux qui déterminent une valeur). L'état des bits de remplissage n'est pas spécifié et ils ne sont pas utilisés pour stocker des valeurs. Ainsi, si vous lisez en utilisant char Dans le cas de données binaires, les choses seraient réduites à la plage de valeurs d'un caractère (en interprétant uniquement les bits de valeur), mais il peut toujours y avoir des bits qui sont simplement ignorés mais qui sont toujours là et lus par memcpy . Tout comme les bits de remplissage dans les objets struct réels. Type unsigned char est garantie de ne pas en contenir. Cela découle de 5.2.4.2.1/2 (C99 TC2, n1124 ici) :

Si la valeur d'un objet de type char est traitée comme un entier signé lorsqu'elle est utilisée dans un fichier la valeur de l'objet CHAR_MIN est le même que celui de SCHAR_MIN et la valeur de CHAR_MAX est le même que celui de SCHAR_MAX . Sinon, la valeur de CHAR_MIN est égal à 0 et la valeur de CHAR_MAX est le même que celui de UCHAR_MAX . _La valeur UCHAR_MAX est égal à 2^CHAR_BIT − 1_

Il ressort de la dernière phrase qu'il n'y a plus de place pour les bits de remplissage. Si vous utilisez char comme le type de votre tampon, vous avez également le problème des débordements : L'attribution explicite d'une valeur quelconque à l'un de ces éléments, qui se situe dans l'intervalle de 8 bits - on peut donc s'attendre à ce qu'une telle affectation soit correcte - mais pas dans la plage d'un char qui est CHAR_MIN .. CHAR_MAX si une telle conversion déborde et provoque des résultats définis par la mise en œuvre, y compris l'augmentation des signaux.

Même si les problèmes relatifs à ce qui précède ne se manifesteraient probablement pas dans les mises en œuvre réelles (ce serait une très mauvaise qualité de la mise en œuvre), il est préférable d'utiliser le bon type dès le début, à savoir unsigned char .

Pour les chaînes de caractères, cependant, le type de données de choix est char qui sera compris par les fonctions string et print. Utilisation de signed char à ces fins me semble être une mauvaise décision.

Pour plus d'informations, lisez this proposal qui contiennent un correctif pour une prochaine version du standard C qui nécessitera finalement signed char n'a pas non plus de bits de remplissage. C'est déjà incorporé dans le document de travail .

34voto

dan04 Points 33306

Un tampon d'octets doit-il être signé signé, un char non signé ou simplement un char ou simplement un tampon char ? Y a-t-il des différences entre C et C++ ?

Une différence mineure dans la façon dont la langue le traite. A énorme différence dans la façon dont la convention le traite.

  • char = ASCII (ou UTF-8, mais le signe est gênant) textuel données
  • unsigned char = octet
  • signed char = rarement utilisé

Et il y a un code qui s'appuie sur sur une telle distinction. Il y a une semaine ou deux, j'ai rencontré un bogue où les données JPEG étaient corrompues parce qu'elles étaient transmises à l'option char* version de notre fonction d'encodage Base64 - qui a "utilement" remplacé tous les UTF-8 invalides dans la "chaîne". Le passage à BYTE alias unsigned char était tout ce qu'il fallait pour le réparer.

12voto

RBerteig Points 23331

Ça dépend.

Si le tampon est destiné à contenir du texte, il est probablement plus logique de le déclarer comme un tableau de char et laissez la plate-forme décider pour vous si elle est signée ou non par défaut. Vous aurez ainsi moins de difficultés à faire entrer et sortir les données de la bibliothèque d'exécution de l'implémentation, par exemple.

Si le tampon est destiné à contenir des données binaires, cela dépend de l'utilisation que vous comptez en faire. Par exemple, si les données binaires sont en réalité un tableau emballé d'échantillons de données qui sont des mesures signées de 8 bits à virgule fixe de l'ADC, alors signed char serait le mieux.

Dans la plupart des cas réels, le tampon n'est que cela, un tampon, et vous ne vous souciez pas vraiment des types des octets individuels parce que vous avez rempli le tampon dans une opération de masse, et vous êtes sur le point de le passer à un analyseur syntaxique pour interpréter la structure de données complexe et faire quelque chose d'utile. Dans ce cas, déclarez-la de la manière la plus simple.

9voto

Pete Kirkham Points 32484

S'il s'agit en fait d'un tampon d'octets 8 bits, plutôt que d'une chaîne de caractères dans la locale par défaut de la machine, alors j'utiliserais uint8_t . Non pas qu'il y ait beaucoup de machines sur lesquelles un caractère n'est pas un octet (ou un octet un octet), mais le fait d'indiquer "ceci est un tampon d'octets" plutôt que "ceci est une chaîne" est souvent une documentation utile.

4voto

Naveen Points 37095

Il est préférable de le définir comme un char non signé. En fait, le type BYTE de Win32 est défini comme un caractère non signé. Il n'y a aucune différence entre C et C++ à ce sujet.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X