Le débordement des caractères signés est-il indéfini dans la plage -255 à 255?

Le code suivant a-t-il un comportement non défini selon GCC en mode C99:

signed char c = CHAR_MAX; // assume CHAR_MAX < INT_MAX c = c + 1; printf("%d", c); 

signed char débordement de caractères signed char provoque un comportement indéfini, mais ce n’est pas ce qui se produit dans le code posté.

Avec c = c + 1 , les promotions d’entier sont effectuées avant l’ajout, c est donc promu int dans l’expression de droite. Comme 128 est inférieur à INT_MAX , cet ajout se produit sans incident. Notez que char est généralement plus étroit que int , mais sur les systèmes rares, char et int peuvent avoir la même largeur. Dans les deux cas, un caractère est promu int en expressions arithmétiques.

Lorsque l’affectation à c est effectuée, si plain char est unsigned sur le système en question, le résultat de l’addition est inférieur à UCHAR_MAX (qui doit être au moins de 255) et cette valeur rest inchangée dans la conversion et l’affectation à c .

Si au lieu de cela, plain char est signed , le résultat de l’ajout est converti en une valeur de caractère signed char avant l’affectation. Ici, si le résultat de l’addition ne peut pas être représenté dans un caractère signed char la conversion “est définie par l’implémentation ou un signal défini par l’implémentation est généré”, conformément au § 6.3.1.3 / 3 de la norme. SCHAR_MAX doit être au moins 127 et si tel est le cas, le comportement est défini par l’implémentation pour les valeurs du code envoyé lorsque le caractère brut est signed .

Le comportement n’est pas indéfini pour le code en question, mais est défini par l’implémentation.

Non, il a un comportement défini par l’implémentation, stockant un résultat défini par l’implémentation ou émettant éventuellement un signal.

Premièrement, les conversions arithmétiques habituelles sont appliquées aux opérandes. Ceci convertit les opérandes en type int et le calcul est donc effectué en type int . Il est garanti que la valeur de résultat 128 est représentable dans int , étant donné INT_MAX est d’au moins 32767 ( 5.2.4.2.1 Taille des types de nombre entier ), de sorte qu’une valeur 128 de type int doit être convertie en type char à stocker. dans c . Si char est non signé, CHAR_MAX est garanti que CHAR_MAX est d’au moins 255; sinon, si SCHAR_MAX prend sa valeur minimale de 127:

6.3.1.3 Entiers signés et non signés

Lorsqu’une valeur de type entier est convertie en un autre type entier, [if] le nouveau type est signé et la valeur ne peut pas y être représentée [,] le résultat est défini par l’implémentation ou un signal défini par l’implémentation est généré.

En particulier, gcc peut être configuré pour traiter char comme signée ou non signée ( -f\[un\]signed-char ); Par défaut, il sélectionne la configuration appropriée pour l’ABI de la plate-forme cible, le cas échéant. Si un caractère signé est sélectionné, toutes les plates-formes cibles gcc actuelles dont je suis au courant ont un octet sur 8 bits (certaines cibles obsolètes, telles que AT & T DSP1600, avaient un octet sur 16 bits) [-128, 127] (8 bits, complément à deux ) et gcc appliquera le calcul modulo arithmétique générant -128 comme résultat:

Le résultat de, ou le signal généré par, la conversion d’un entier en un type entier signé lorsque la valeur ne peut pas être représentée dans un object de ce type (C90 6.2.1.2, C99 et C11 6.3.1.3).

Pour la conversion en un type de largeur N, la valeur est réduite modulo 2 ^ N pour être dans la plage du type; aucun signal n’est élevé.