Spécificateur de Format unsigned char
Dire que je veux imprimer unsigned char
:
unsigned char x = 12;
ce qui est correct. Ce:
printf("%d",x);
ou ceci:
printf("%u",x);
?
Le truc, c'est d'ailleurs sur j'ai DONC rencontré ce genre de discussion:
-Même avec ch changé de unsigned char, le comportement du code n'est pas défini par la norme. C'est parce que la unsigned char est promu à un int (normal des implémentations C), de sorte que l'int est passé à printf pour le spécificateur %u. Toutefois, %u s'attend à un unsigned int, de sorte que les types ne correspondent pas, et le C standard ne définit pas le comportement
-Votre commentaire est incorrect. Le C11 norme indique que les indicateurs de conversion doit être du même type que l'argument de fonction elle-même, pas le promu type. Ce point est également soulevé dans la description de l'hh modificateur de longueur: "l'argumentation ont été promus en fonction de l'entier des promotions, mais sa valeur doit être convertie en signed char ou unsigned char avant impression"
Alors, qui est-elle correcte? Aucune source fiable dire sur cette question? (Dans ce sens, nous devrions également imprimer unsigned short
int avec %d, car il peut être promu à int
?).
OriginalL'auteur | 2014-12-18
Vous devez vous connecter pour publier un commentaire.
Correcte est*:
C'est à cause de argument par défaut promotions comme
printf()
est variadic fonction. Cela signifie queunsigned char
valeur est toujours promuint
.De N1570 (C11 projet)
6.5.2.2/6
appels de Fonction (l'emphase est mienne):et
6.5.2.2/7
la subdivision dit:Entier ces promotions sont définis dans
6.3.1.1/2
Booléens, caractères, et les nombres entiers:Cette citation à répondre à votre deuxième question de
unsigned short
(voir commentaire ci-dessous).* à l'exception de plus de 8 bits
unsigned char
(par exemple, il pourrait occuper 16 bits), voir @chux de réponse.OriginalL'auteur Grzegorz Szpetkowski
Corriger spécificateur de format pour
unsigned char x = 12
dépend d'un certain nombre de choses:Si
INT_MAX >= UCHAR_MAX
, ce qui est souvent le cas, utilisez"%d"
. Dans ce cas, ununsigned char
est promuint
.Utiliser autrement
"%u"
(ou"%x"
,"%o"
). Dans ce cas, ununsigned char
est promuunsigned
.À jour les compilateurs de soutien de la
"hh"
modificateur de longueur, ce qui compense cette ambiguïté. Devraitx
obtenir une promotion àint
ouunsigned
en raison de la norme de promotions de la part des paramètres variants.,printf()
convertitunsigned char
avant l'impression.Si vous traitez avec un vieux compilateur sans
"hh"
ou à la recherche de très du code portable, utiliser un cast expliciteLa même question/réponse s'applique à
unsigned short
, attendreINT_MAX >= USHRT_MAX
et l'utilisation"h"
au lieu de"hh"
.d
avec unsigned char peut causer ub, veuillez voir la discussion (voir mon dernier commentaire): stackoverflow.com/a/36350763/4082723 j'aimerais entendre votre opinion.Lors de l'impression
char
,unsigned char
,signed char
...int
,unsigned
, considérer ce qui est défini et de commencer avec 2 spécifications: ( 1) Tout rang inférieur entier queint/unsigned
se qualifient pourint/unsigned
. 2)...
argument: "... un promu type est un entier signé de type, l'autre promu type est le type entier non signé, et la valeur est représentable dans les deux types" (C11 §6.5.2.2). Donc, lors de l'examen si”hhd”, “hhu”, … “d”, “u”
, est défini avecprintf()
, le type de document n'est pas pertinent, seul le promu type et la valeur est un sujet de préoccupation.Ensuite, nous avons seulement besoin de ces affaires pour voir si le comportement est défini: A) les Spécificateurs de “d”, “hd”, “hhd” avec un
int
argument (ouunsigned
argument dans la gamme deint
) et la valeur est dans la gamme deint
,short
,signed char
, B) “...u”,“...”, “...x”, “X ...” avec ununsigned
argument (ouint
argument dans la gamme deunsigned
), de toute valeur. IOriginalL'auteur chux
À la fois,
unsigned char
etunsigned short
, peut en toute sécurité être imprimé avec%u
. L'argument par défaut promotions convertir, soit pourint
ou àunsigned int
. Si ils sont promus à la dernière, tout va bien (le spécificateur de format et du type passé de match), sinon C11 (n1570) 6.5.2.2 p6, premier alinéa, s'applique:Le standard est tout à fait clair que l'argument par défaut promotions s'appliquent à la variadic arguments de
printf
, par exemple, il est mentionné de nouveau pour le (la plupart du temps inutile)h
ethh
les modificateurs de longueur (ibid. 7.21.6.1 p7, emph. le mien):h
ethh
sont la plupart du temps inutile pourprintf()
, mais ils étaient pour la plupart ajoutée pour la symétrie, car ils ne sont pas inutiles pourscanf()
.Je pense que l'explique. Je me demandais à ce sujet et suis tombé sur ce.
OriginalL'auteur mafso
Pour la croix-plate-forme de développement, en général, je contourner la promotion de problème en utilisant
inttypes.h
http://pubs.opengroup.org/onlinepubs/009695399/basedefs/inttypes.h.html
Cet en-tête (qui est dans le standard C99) définit tous les printf types pour les types de base. Donc, si vous voulez un u_int8_t (une syntaxe qui, je vous suggère fortement d'utiliser à la place de unsigned char) je voudrais utiliser
unsigned char
peut ne pas correspondre à la plage deuint8_t
. La conformité de la C11 compilateur ne pas avoir à mettre en œuvreuint8_t
- "Ces types sont en option." –quand il est souhaitable de provoquer une erreur de compilation au lieu de la conduite fautive lorsqu'une plate-forme n'ont pas 8 bits adressables unités.
OriginalL'auteur IdeaHat