C comparación char y int

En el bloque de código a continuación, ¿cuál es la conversión implacable que tiene lugar en la statement if para 7? Tendría que haber terminado (0x98 <= 0x07) pero eso no es lo que sucede cuando la condición se vuelve verdadera y DoMyStuff recibe una llamada.

char minstogo = 0x98; if(minstogo <= 7) { DoMyStuff(); } 

Siempre que tenga un operador binario (uno de + - * / % << >> & | ^ == != <= >= ) Entre dos operandos integrales de diferentes tipos, los dos tipos se convierten a un tipo común antes Se realiza la operación. Las reglas para decidir el tipo de conversión son (de la sección 6.3.1.8 del estándar C99):

Si ambos operandos tienen el mismo tipo, no se requieren más conversiones.

De lo contrario, si ambos operandos tienen tipos enteros con signo o si ambos tienen tipos de enteros sin signo, el operando con el tipo de rango de conversión de entero menor se convierte al tipo del operando con mayor rango.

De lo contrario, si el operando que tiene un tipo entero sin signo tiene un rango mayor o igual al rango del tipo del otro operando, entonces el operando con tipo entero con signo se convierte al tipo del operando con tipo entero sin signo.

De lo contrario, si el tipo del operando con tipo entero con signo puede representar todos los valores del tipo del operando con tipo entero sin signo, entonces el operando con tipo entero sin signo se convierte al tipo del operando con tipo entero con signo.

De lo contrario, ambos operandos se convierten al tipo de entero sin signo correspondiente al tipo del operando con el tipo de entero con signo.

En este caso, char podría ser un tipo entero con signo o sin signo, su firmeza está definida por la implementación. Sin embargo, afortunadamente, un int puede representar todos los valores posibles de un char , tanto si el char está firmado como si no, asumiendo que está en un sistema donde los char s son de 8 bits y los int s son de al menos 16 bits.

Si se firma char , entonces se aplica el segundo párrafo anterior, por lo que ambos operandos se convierten a int (el tipo con rango más alto; el rango se define de una manera un tanto complicada, pero es esencialmente equivalente al tamaño de bit del tipo). Como 0x98, como un char signo, es negativo, se convierte al entero -104, que es entonces menor que 7.

Si, en cambio, char no está firmado, entonces se aplica el cuarto párrafo. El char sin firmar se convertiría a 152 como un int , que es mayor que 7.

Nunca confíe en que los caracteres estén firmados o sin firmar. Si necesita enteros de 8 bits con un carácter de firma determinado, utilice explícitamente caracteres con unsigned char o unsigned char , o use los tipos C99 int8_t y uint8_t , definidos int .

Es muy fácil ser mordido por errores sutiles causados ​​por las reglas de promoción de enteros. Le recomiendo que siempre compile con -Wall with gcc, que le advertirá sobre las comparaciones entre enteros con signo y sin signo, que con frecuencia son una causa de errores.

Lo que probablemente suceda aquí es que char es un valor firmado y, por lo tanto, 0x98 se está registrando como un número negativo. Por lo tanto es menos de 7

También en este escenario, 7 no sufrirá ninguna conversión. En su lugar, el carácter se ampliará al mismo tipo integral que 7 y luego se realizará una comparación.

Con los caracteres representados como un byte de ocho bits, establecer minstogo en 0x98 es un valor binario de 10011000. El bit de signo está establecido, es un valor entero negativo. Es probable que desee un carácter no firmado para que la prueba evalúe como falso.

Se evaluará de la misma manera que 0x98 <= 7 menos que el tipo de char la plataforma tenga el valor predeterminado de firmado y CHAR_BIT sea ​​8. En ese caso, el valor de minstogo será negativo y minstogo <= 7 será verdadero.

0x98 es 152.

Ya que ha declarado un “char” y no un “char sin firmar”, está intentando asignar 152 a un tipo que tiene un rango de -128 – 127 .

Esto se va a desbordar y le dará un número negativo, que será <7 (0x07).

Usando su comstackdor con su configuración actual, char es un tipo firmado: y como el bit de orden superior (0x80) de su valor está establecido, ese valor es negativo. Cuando se amplía el minstogo, ese signo negativo se conserva (a través de sign-extension), por lo que el minstogo se amplía a un entero negativo (por ejemplo, 0xFF98), que es menor que 7.