Un simple progtwig en C no es el esperado

Estaba haciendo este progtwig simple y mi mente se atascó

#include int main() { signed int a; signed char c; unsigned char b; b = 0xf4; a = (signed)b; // 1)this assignment should be same c = (signed)b; printf("%d\n",a); a = c; // 2)as this one printf("%d \n",a); return 0; } a = 244, a = -12 

Traté de asegurarme de que la asignación sea lo más fluida posible, pero recibo dos respuestas diferentes y esperaba ambas como -12. ¿Qué pequeña cosa me falta?


La pregunta relevante fue

 { b = 0xf4; c = 0xf4; a = (signed int)b; //trying to save sign but get 244 printf("%d\n", a); a = c; //sign saved here and got -3 printf("%d", a); } 

244, -3

así que estoy tratando de guardar el signo de un char sin firmar. ¿Es esto posible de esta manera?

  signed char c; unsigned char b; b = 0xf4; /* ... */ c = (signed)b; 

El valor de b es 0xf4 ( 244 ) pero el tipo c ( signed char ) solo puede contener valores entre -128 y 127 (en su implementación). Entonces, cuando se asigna 244 a c , primero se convierte a signed char y C dice que esta conversión de enteros está definida por la implementación. gcc ya que la mayoría de las implementaciones simplemente envuelve el módulo 256 y es por eso que el valor de c es -12 .

Aquí está la documentación de gcc :

http://gcc.gnu.org/onlinedocs/gcc/Integers-implementation.html

“Para la conversión a un tipo de ancho N, el valor se reduce en módulo 2 ^ N para estar dentro del rango del tipo”

El problema se encuentra aquí:

 c = (signed)b; 

la conversión del valor de b, 244, a un carácter firmado, lleva a un desbordamiento de entero, lo que da como resultado el valor de -12 que se ve. Cambiar el tipo de c a signed int resuelve el problema.

A mi entender, la salida de 244 es correcta. Primero, b se inicializa a un valor de 244 expresado como un literal hexadecimal, que luego se convierte al signed int a con signed int a , que puede contener el valor de 244 . De acuerdo con la especificación de las cadenas de formato printf , la salida de 244 es lo que se espera.

Evento si no escribe ‘b’ por firmado, obtendrá los mismos resultados.

En primera asignacion

a = (firmado) b;

está cargando un int firmado (16bit / 32bit / 64bit) con 0xf4 que puede contener, y como msb es ‘0’ el resultado será 244.

Si su int hubiera tenido una longitud de 8 bits, el resultado será ‘-12’.

En el segundo caso, debe obtener ‘-12’ porque el complemento de 2 de ‘-12’ es 0xf4.