u_int8_t vs unsigned char
Quel est l'avantage de l'utilisation de uint8_t
sur unsigned char
en C?
Je sais que sur presque tous les systèmes uint8_t
est juste un typedef pour unsigned char
,
alors pourquoi l'utiliser?
Vous devez vous connecter pour publier un commentaire.
Il des documents à votre intention, vous serez le stockage de petits nombres, plutôt que d'un personnage.
En outre, il semble plus agréable si vous utilisez d'autres typedefs comme
uint16_t
ouint32_t
.unsigned char
ousigned char
documents à l'intention de trop, car sans fioritureschar
est ce que montre vous travaillez avec des personnages.unsigned
étaitunsigned int
par définition?unsigned char
etuint8_t
ne sont pas de types distincts, voir par exemple ideone.com/GMV0uDchar
semble impliquer un personnage, alors que dans le contexte d'une chaîne UTF8, il peut être en un seul octet d'un caractère multi-octets. À l'aide de u_int8_t pourraient le rendre clair que l'on ne doit pas s'attendre à un personnage dans chaque position-à-dire que chaque élément de la chaîne de caractères ou un tableau est un entier arbitraire que l'on ne doit pas faire de la sémantique des hypothèses sur. Bien sûr, tous les programmeurs C le savent, mais il peut pousser les débutants à se poser les bonnes questions.unsigned char
n'est pas vraiment utilisé pour stocker les caractères en premier lieu, de sorte que "l'intention" question est discutable.char
est une abréviation de caractère est assez clair), mais en effet ne pas en pratique parce que c'était historiquement, le seul standard de 8 bits type de données jusqu'à ce que le C99inttypes.h
est apparu. Maintenant que nous avonsinttypes.h
, je pense que c'est en fait tous sur l'intention, lorsque l'on compare les types de données d'origine et la nouvelle(u)int_(least/fast)N_t
types de données, et sur l'intention, et l'assurance que le code compile avec largeur exacte ou pas du tout quand il s'agit de(u)intN_t
.Juste pour être pédant, certains systèmes peuvent ne pas avoir un 8 bits type. Selon Wikipédia:
Donc
uint8_t
n'est pas garanti pour exister, mais pour toutes les plates-formes 8 bits = 1 octet. Certaines plateformes embarquées peuvent être différentes, mais qui devient très rare. Certains systèmes peuvent définirchar
de types 16 bits, dans ce cas, il ne sera probablement pas en 8 bits type de toute nature.Autre que celle (mineur) problème, @Mark Rançon de la réponse est le meilleur à mon avis. Utilisez celle qui montre clairement ce que vous êtes en utilisant les données pour.
Aussi, je suis en supposant que vous vouliez dire
uint8_t
(la norme de définition de type de C99 fourni dans lestdint.h
en-tête) plutôt que deuint_8
(ne faisant pas partie de la norme).CHAR_BIT > 8
sont de plus en moins rares, pas plus.uint8_t
(ou définition de type pour qui). C'est parce que le 8 bits type de aurait les bits non utilisés dans la représentation de stockage, quiuint8_t
ne doit pas avoir.typedef unsigned integer type uint8_t; // optional
Donc, en substance, une C++ standard conforme de la bibliothèque n'est pas nécessaire de définir u_int8_t à tous (voir le commentaire //facultatif)uint_least8_t
à indiquer correctement l'intention et le fait que le type ne peut pas être réellement en 8-bits.Le but est d'écrire de la mise en œuvre-le code indépendant de la.
unsigned char
n'est pas garanti d'être un 8 bits type.uint8_t
est (si disponible).sizeof(unsigned char)
sera de retour1
de 1 octet. mais si un système de char et int sont de la même taille, par exemple, 16-bits alorssizeof(int)
est également de retour1
#ifdef UINT8_MAX
Comme vous l'avez dit, "presque chaque système".
char
est probablement l'un des moins susceptibles de changer, mais une fois que vous commencez à utiliseruint16_t
et amis, à l'aide deuint8_t
mélanges de mieux, et peut même faire partie d'une norme de codage.Dans mon expérience, il y a deux endroits où nous voulons utiliser u_int8_t à dire 8 bits (et uint16_t, etc) et où l'on peut avoir des champs de taille inférieure à 8 bits. Les deux endroits sont les cas où l'espace des questions et nous avons souvent besoin de regarder raw dump des données lors du débogage et doivent être en mesure de déterminer rapidement et de ce qu'il représente.
La première est dans les protocoles RF, en particulier dans la bande étroite des systèmes. Dans cet environnement, nous pouvons avoir besoin pour emballer autant d'informations que possible, dans un seul message. La deuxième est en flash de stockage où l'on peut avoir très peu d'espace (comme dans les systèmes embarqués).
Dans les deux cas, nous pouvons utiliser des paniers-structure de données dans laquelle le compilateur va prendre soin de l'emballage et le déballage pour nous:
La méthode que vous utilisez dépend de votre compilateur. Vous pouvez aussi avoir besoin de l'appui de plusieurs des compilateurs différents avec les mêmes fichiers d'en-tête. Ce qui se passe dans les systèmes embarqués où les périphériques et les serveurs peuvent être complètement différents - par exemple, vous pouvez avoir un BRAS de l'appareil qui communique avec un x86 Linux serveur.
Il existe quelques inconvénients à l'utilisation de paniers structures. Le plus grand piège est que vous devez éviter de référence à l'adresse d'un membre. Sur les systèmes avec mutibyte aligné des mots, cela peut entraîner un mauvais alignement de l'exception - et un coredump.
Certaines personnes s'inquiètent également de la performance et affirment que l'utilisation de ces paniers structures vont ralentir votre système. Il est vrai que, derrière les coulisses, le compilateur ajoute le code pour accéder aux données non alignées membres. Vous pouvez le voir en regardant le code assembleur dans votre IDE.
Mais depuis paniers structures sont les plus utiles pour la communication et le stockage des données les données peuvent être extraites dans un non-emballés représentation du travail dans la mémoire.
Normalement nous n'avons pas besoin de travailler avec l'ensemble du paquet de données dans la mémoire de toute façon.
Voici de discussion:
pragma pack(1), ni __attribute__ ((alignés (1))) fonctionne
Est du ccg __attribute__((emballé)) /#pragma pack dangereux?
http://solidsmoke.blogspot.ca/2010/07/woes-of-structure-packing-pragma-pack.html
Il y a peu. Du point de vue de la portabilité,
char
ne peut pas être inférieure à 8 bits, et rien ne peut être plus petit quechar
, donc si une œuvre a un entier non signé de 8 bits type entier, ça va êtrechar
. Alternativement, il peut ne pas en avoir un à tous, à quel point touttypedef
astuces sont discutable.Il pourrait être utilisé pour mieux documenter votre code, en ce sens qu'il est clair que vous avez besoin d'octets de 8 bits, et rien d'autre. Mais dans la pratique c'est une attente raisonnable en matière de pratiquement n'importe où déjà (il y a des DSP plates-formes sur lesquelles il n'est pas vrai, mais les chances de votre code en cours d'exécution il est mince, et vous pourriez tout aussi bien l'erreur à l'aide d'un statique affirmer en haut de votre programme sur une telle plate-forme).
typedef struct { unsigned i :8; } uint8_t;
mais vous auriez à utiliser commeuint8_t x; x.i = ...
de sorte qu'il faudrait être un peu plus lourd.unsigned char
pour être en mesure de conserver des valeurs entre 0 et 255. Si vous pouvez le faire en 4 bits, mon chapeau est hors de vous.uint8_t
à la mise en œuvre. Je me demande, ne les compilateurs pour les Dsp avec 16 caractères généralement en œuvreuint8_t
, ou pas?uint8_t
à tous - il faut l'avoir si et seulement si elle a un type correspondant. Il est, cependant, nécessaire de fourniruint8_least_t
, qui est au moins 8 bits (mais peut-être plus).#include <stdint.h>
, et l'utilisationuint8_t
. Si la plate-forme, il va se donner à vous. Si la plate-forme ne l'a pas, votre programme ne compilera pas, et la raison sera clair et simple.uint8_t
existe à tous, ça va êtreunsigned char
de toute façon.sizeof(uint8_t) == sizeof(char)
même siUCHAR_MAX != 255
, mais c'est OK, c'est pourquoi les types n'ont pas à utiliser toute leur stockage bits. Par "claque dans le dos de la tête" bien sûr, je veux dire "faire un passionné mais poli demande de fonctionnalité". Ils sont en droit de le refuser, mais le degré de confiance sont-ils que vous n'aurez pas recours à la violence? 😉uint8_least_t
et appliquer le modulo-256 dépassement de vous-même. Je devine que vous pouvez l'écrire ainsi que sur toute vaguement l'optimisation du compilateur oùuint8_least_t
est de 8 bits, tous les extra ops sont gommés.unsigned char
est spécifiquement requis pour l'utilisation de toutes les capacités de stockage de bits entièrement par l'ISO C et C++. Voir 6.2.6.1/3 (et la note de bas de page) pour C99, et 3.9.1/1 pour C++03.unsigned char
(qui dans cet exemple est de 16 bits) utilise tous les bits, mais autant que je sacheuint8_t
ne pas avoir à le faire. Doncuint8_t
peut être plus petite queunsigned char
dans la gamme, bien que, évidemment, pas dans la taille de stockage. Donc je ne vois pas pourquoi il devrait être difficile pour le compilateur de l'écrivain à l'appui deuint8_t
. Il peut être monstrueusement inefficace, mais c'est une question distincte.uint8_t
existe, alorsunsigned char
doit également être de 8 bits, il ne serait pas interdire une mise en œuvre de la fabrication deuint8_t
8 bits étendu de type entier. Il serait vraiment utile d'avoir un 8 bits type non signé qui ne reçoit pas le spécial aliasing traitementunsigned char
, et rien n'interdirait de mise en œuvre de la fabrication deuint8_t
être un tel type [à mon humble avis, la bonne manière de définir ce type serait de lui donner un nom spécial qui pourrait être un alias deuint8_t
sur des implémentations qui prennent en charge les derniers...Qui est vraiment important, par exemple lors de l'écriture d'un analyseur de réseau.
en-têtes de paquets sont définies par la spécification de protocole, pas par le moyen d'une plate-forme particulière compilateur C fonctionne.
Sur presque tous les systèmes que j'ai rencontré u_int8_t == unsigned char, mais ce n'est pas garanti par la norme. Si vous essayez d'écrire du code portable et il est important, exactement ce que la taille de la mémoire, utilisez u_int8_t. Sinon utiliser unsigned char.
uint8_t
toujours correspond à la gamme et la taille deunsigned char
et le rembourrage (aucun) lorsqueunsigned char
est de 8 bits. Lorsqueunsigned char
n'est pas de 8 bits,uint8_t
n'existe pas.unsigned char
est de 8 bits, estuint8_t
la garantie d'unetypedef
de celle-ci et pas untypedef
d'un étendu unsigned integer?unsigned char/signed char/char
sont les plus petits de type ni inférieure à 8 bits.unsigned char
a pas de rembourrage. Pouruint8_t
être, il doit être de 8 bits, pas de rembourrage, existent en raison d'une mise en œuvre à condition de type entier: il correspond aux exigences minimales en matière deunsigned char
. Quant à "... la garantie d'une définition de type..." ressemble à une bonne question à poste.