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 en CHAR_MAX
, se ajusta a CHAR_MIN
. ¿Está garantizado este comportamiento? ¿O va a ser un comportamiento indefinido o un comportamiento específico de implementación? ¿Qué dice el estándar C99 sobre esto?
[Nota: ¿Qué sucede cuando se da un valor mayor que CHAR_MAX (127) a char o C- por qué char c = 129 se convertirá en -127? no aborda esta pregunta porque hablan de asignar un valor fuera de rango y no incrementar un valor a un valor fuera de rango.]
c
char
language-lawyer
standards
integer-overflow
Aprendiz solitario
fuente
fuente
Respuestas:
La pregunta es doble: en primer lugar, es
evaluado de manera diferente de
y la respuesta es no, no lo es , porque C11 / C18 6.5.16.2p3 :
Entonces, la pregunta es qué sucede en
c = c + 1
. Aquí los operandos se+
someten a las conversiones aritméticas habitualesc
y1
, por lo tanto, son promovidos aint
, a menos que una arquitectura realmente loca requiera quechar
se promuevaunsigned int
.+
Luego se evalúa el cálculo de , y el resultado, de tipoint
/unsigned int
se vuelve a convertirchar
y se almacena enc
.Hay 3 formas definidas por la implementación en las que esto puede evaluarse:
CHAR_MIN
es 0 y, porchar
lo tanto, no está firmado.Cualquiera de los dos
char
es promovidoint
aounsigned int
y si se promociona a unint
, entoncesCHAR_MAX + 1
necesariamente encajará en unint
también, y no se desbordará, o siunsigned int
puede encajar o ajustarse a cero. Cuando el valor resultante, que es numéricamenteCHAR_MAX + 1
o0
después de la reducción del módulo, vuelva ac
, después de la reducción del módulo, se convertirá en 0, es decirCHAR_MIN
De
char
lo contrario, se firma, entonces siCHAR_MAX
es menor queINT_MAX
, el resultado deCHAR_MAX + 1
se ajustará aint
, y el estándar C11 / C18 6.3.1.3p3 se aplica a la conversión que ocurre después de la asignación :O, si f
sizeof (int) == 1
ychar
está firmado, entonceschar
se promociona a anint
, yCHAR_MAX == INT_MAX
=>CHAR_MAX + 1
causará un desbordamiento de enteros y el comportamiento será indefinido .Es decir, los posibles resultados son:
Si
char
es un tipo entero sin signo, el resultado es siempre0
, es decirCHAR_MIN
.De
char
lo contrario, es un tipo entero con signo, y el comportamiento está definido por la implementación / indefinido:CHAR_MIN
o algún otro valor definido por la implementación,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ónc++
será el valorc
anterior al incremento; para los otros tres, será el valor dec
después del incremento.fuente
sizeof(int) == 1
requeriríaCHAR_BITS >= 16
, ¿verdad?<pedantic>
IDK sobreCHAR_BITS
pero loCHAR_BIT
haría>= 16</pedantic>
.char
siempre debe estar sin firmar por defecto.