Mi código:
#include <stdio.h>
#include <limits.h>
int main()
{
char c = CHAR_MAX;
c += 1;
printf("CHAR_MIN=%d CHAR_MAX=%d c=%d (%c)\n", CHAR_MIN, CHAR_MAX, c, c);
}
Salida:
CHAR_MIN=-128 CHAR_MAX=127 c=-128 ()
Vemos que cuando incrementamos un char
conjunto de variables a CHAR_MAX
, que se envuelve alrededor de CHAR_MIN
. Se garantiza este comportamiento? O es que va a ser un comportamiento indefinido o comportamiento aplicación especificado? ¿Qué dice la norma C99 de esto?
[Nota: ¿Qué pasa cuando el valor más grande que dar CHAR_MAX (127) de carbón o C- qué Char c = 129 se convertirá en -127? no se refiere a esta pregunta porque hablan de la asignación de un valor fuera de rango no incrementar un valor a un valor fuera de rango.]
La pregunta es doble: En primer lugar, es
char c = CHAR_MAX;
c += 1;
evaluado de manera diferente a partir de
char c = CHAR_MAX;
c = c + 1;
y la respuesta es no, no lo es , porque C11 / C18 6.5.16.2p3 :
- Una asignación de compuesto de la forma
E1 op = E2
es equivalente a la expresión de asignación sencillaE1 = E1 op (E2)
excepto que el lvalueE1
se evalúa sólo una vez, y con respecto a una llamada de función indeterminada-secuenciado, la operación de una asignación de compuesto es una única evaluación. SiE1
tiene un tipo atómico, misiones compuesto es una operación de lectura-modificación-escritura conmemory_order_seq_cst
la semántica de orden memoria. 113)
Entonces, la pregunta es lo que sucede en c = c + 1
. Aquí los operandos a +
someterse a las conversiones aritméticas habituales, y c
, y 1
, por tanto, son promovidos a int
, a menos que una arquitectura realmente loco requiere que char
se promueve a unsigned int
. El cálculo de +
se evalúa a continuación, y el resultado, de tipo int
/ unsigned int
es de nuevo convertido a char
y se almacena en c
.
Existen 3 formas de ejecución definidos en los que esto, entonces se puede evaluar:
CHAR_MIN
es 0 y por lo tantochar
es sin signo.Ya sea
char
a continuación, se promueve aint
ounsigned int
y si se promueve a unaint
, a continuación,CHAR_MAX + 1
se ajusta necesariamente a unaint
también, y no se desborde, o siunsigned int
se puede encajar o dar un ciclo a cero. Cuando el valor resultante, que es numéricamente ya seaCHAR_MAX + 1
o0
después de la reducción de módulo, de nuevo ac
, después de la reducción de módulo se convertirá en 0, es decir,CHAR_MIN
De lo contrario
char
se firma, a continuación, siCHAR_MAX
es menor queINT_MAX
, el resultado deCHAR_MAX + 1
cabrá unaint
, y el estándar C11 / C18 6.3.1.3p3 se aplica a la conversión que ocurre sobre asignación :- De lo contrario, el nuevo tipo se firma y el valor no puede ser representado en ella; ya sea el resultado es definido por la implementación o se eleva una señal definido por la implementación.
O, si y sólo si
sizeof (int) == 1
, ychar
está firmado, entonceschar
es promovido a unaint
, yCHAR_MAX == INT_MAX
=>CHAR_MAX + 1
ocurre un exceso de número entero y la estarán indefinidos comportamiento .
Es decir, los posibles resultados son:
Si
char
es un tipo entero sin signo, el resultado es siempre0
, es decirCHAR_MIN
.De lo contrario,
char
es un tipo entero con signo, y el comportamiento es definido por la implementación / indefinido:CHAR_MIN
o algún otro valor definido por la implementación,- una señal definida por la implementación se eleva, posiblemente terminar el programa,
- o el comportamiento no está definido en algunas plataformas donde
sizeof (char) == sizeof (int)
.
Todas las operaciones de incremento c = c + 1
, c += 1
, c++
y ++c
tienen los mismos efectos secundarios en la misma plataforma. El valor evaluado de la expresión c++
será el valor de c
antes del incremento; para los otros tres, será el valor de c
después del incremento.