Résumé: Le résultat est la mise en œuvre définies et très vraisemblablement -1
, mais c'est compliqué, au moins en principe.
Les règles relatives à débordement sont différents pour les opérateurs contre les conversions, et pour les types signés vs non signé types -- et les règles de conversion changé entre C90 et C99.
Comme de C90, le débordement d'un opérateur ayant signé des opérandes entiers ("overflow" ce qui signifie que le résultat mathématique ne peut pas être représenté dans l'expression du type) a un comportement indéfini. Pour les opérandes entiers, le comportement est bien définie, comme d'habitude wraparound (strictement parlant, la norme n'appelle pas cela un "dépassement"). Mais votre déclaration:
char foo = 255;
ne pas utiliser toute les opérateurs (l' =
est un initialiseur, pas une cession), de sorte que rien de tout ce qui s'applique dans ce cas.
Si le type char
peut représenter la valeur 255
(ce qui est vrai soit de plain char
n'est pas signée ou si CHAR_BIT >= 9
), puis, bien sûr, le comportement est bien définie. L' int
expression 255
est implicitement converti en char
. (Depuis CHAR_BIT >= 8
, il n'est pas possible pour ce cas particulier d'invoquer la non signé enveloppante.)
Sinon, la conversion, vous obtenez un résultat qui ne peut pas être stockée dans un char
.
Comme de C90, le résultat de la conversion de la mise en œuvre est définie -- ce qui signifie qu'il est garanti à l'ensemble foo
pour certains de la valeur au sein de la gamme de type char
, et vous pouvez déterminer ce que cette valeur est par la lecture de la mise en œuvre de la documentation, qui est nécessaire pour vous raconter comment la conversion fonctionne. (Je n'ai jamais vu une mise en œuvre lorsque la valeur stockée est rien d'autre qu' -1
, mais le résultat est en principe possible.)
C99 a changé la définition, de sorte qu'un débordement de conversion d'un type signé , soit des rendements de mise en œuvre définies par résultat ou soulève une mise en œuvre définies par le signal.
Si un compilateur choisit la seconde solution, alors il doit document signal est déclenché.
Donc ce qui se passe si une mise en œuvre définies par le signal est déclenché? La Section 7.14 de la norme dit:
L'ensemble des signaux, leur sémantique et leur valeur par défaut
la manipulation de la mise en œuvre est définie par
Il n'est pas entièrement clair (pour moi) que la gamme de comportements possibles pour le "défaut de la manipulation de signaux. Dans le pire des cas, je suppose que ce signal pourrait mettre fin au programme. Vous pourrait ou ne pourrait pas être en mesure de définir un gestionnaire de signal qui capte le signal.
7.14 dit aussi:
Si la fonction retourne une valeur, si la valeur de sig est SIGFPE,
SIGILL, SIGSEGV, ou de toute autre mise en valeur définie
correspondant à un calcul d'exception, le comportement est indéfini;
sinon le programme va reprendre l'exécution à l'endroit ou elle a été
interrompu.
mais je ne pense que ce qui s'applique, depuis un débordement de conversion n'est pas un "calcul d'exception", car le terme est utilisé ici. (À moins que la mise en œuvre définies par le signal qui arrive à être SIGFPE
, SIGILL
ou SIGSEGV
- mais ce serait ridicule).
Donc, en fin de compte, si une mise en œuvre choisit d'élever un signal en réponse à un débordement de conversion, le comportement (et pas seulement le résultat) est au moins de mise en œuvre définis, et il pourrait y avoir des circonstances dans lesquelles il pourrait être indéfini. En tout cas, il ne semble pas être n'importe quel portable façon de traiter avec un tel signal.
Dans la pratique, je n'ai jamais entendu parler d'une application qui tire parti de la nouvelle formulation du C99. Pour tous les compilateurs j'ai entendu, le résultat de la conversion est mise en œuvre définies-et très probablement les rendements de ce que vous attendez d'un 2-complément de troncature. (Et je ne suis pas du tout convaincu que ce changement dans C99 était une bonne idée. Si rien d'autre, il fait cette réponse environ 3 fois plus longtemps qu'elle serait autrement nécessaire.)