n=256;
convertit la valeur entière signée 256
en uint8_t
, puis l'affecte à n
. Cette conversion est définie par la norme pour prendre la valeur modulo-256, de sorte que n
est définie sur 0
.
Vous ne savez pas où vous pouvez trouver une table, mais les règles pour les conversions entières sont à 6.3.1.3:
1 Lorsqu'une valeur de type entier est converti en un autre type entier autre que _Bool, si la valeur peut être représentée par le nouveau type, elle est inchangée.
2 Dans le cas contraire, si le nouveau type est non signé, la valeur est convertie par de façon répétée en ajoutant ou en soustrayant une supérieure à la valeur maximale qui peut être représenté dans le nouveau type jusqu'à ce que la valeur est dans la plage de la nouvelle type.49)
3 dans le cas contraire, le nouveau type est signé et la valeur ne peut pas être représentée dans elle; soit le résultat est mise en œuvre défini ou un signal de mise en œuvre défini est élevé
Comme le souligne AndreyT dehors, cela ne couvre pas ce qui se passe lorsqu'un hors plage de valeurs se produit lors d'un calcul, comme opposé à lors d'une conversion. Pour les types non signés qui est couvert par 6.2.5/9:
Un calcul impliquant non signés opérandes ne peut jamais déborder, car un résultat qui ne peut pas être représenté par le type entier non signé résultant est réduit modulo le numéro est supérieur à la plus grande valeur que peut être représenté par le type résultant.
Pour les types signés, 3.4.3/3 dit:
Exemple Un exemple de comportement non défini est le comportement sur débordement d'entier.
(indirect, je sais, mais je suis trop paresseux pour continuer à chercher la description explicite quand c'est l'exemple canonique du comportement indéfini).
Notez également qu'en C, les règles de promotion d'entier sont assez compliquées. Les opérations arithmétiques sont toujours effectuées sur des opérandes du même type, donc si votre expression implique des types différents, il existe une liste de règles pour décider du type de l'opération. Les deux opérandes sont promus à ce type commun. C'est toujours au moins un int, cependant, pour un petit type comme uint8_t
, l'arithmétique sera faite dans un int
et reconverti en uint8_t
lors de l'assignation au résultat. Par conséquent, par exemple:
uint8_t x = 100;
uint8_t y = 100;
unsigned int z = x * y;
résultats à 10 000, pas 16 qui serait le résultat si z était un uint8_t
aussi.
De même, est-il acceptable d'utiliser les macros PRI * C99? Comment sont-ils nommés?
Acceptable à qui? Cela ne me dérange pas, mais vous voudrez peut-être vérifier si votre compilateur les prend en charge ou non. GCC fait dans la première version que j'ai traîné, 3.4.4. Ils sont définis en 7.8.1. Si vous n'avez pas de copie de la norme C, utilisez ceci: http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf. C'est un "brouillon" de la norme, publié quelques temps après la publication de la norme et incluant quelques corrections.