Pregunta Desbordamiento de datos al comparar los valores


Tengo una duda de los siguientes 2 fragmentos de código.

Ejecuté este código en una máquina de 64 bits (x86_64-linux-gnu). Puedo ver el valor Val se desborda cuando el tipo de datos es unsigned integer.

#include<stdio.h>
main()
{
    unsigned int Val = 0xFFFFFFFF-15, Val2 = 0xFFFFFFFF;
    if (Val+16 < Val2)
    {
        printf("Val is less than Val2\n");
    }
}

Si el tipo de datos es unsigned char no se desborda.

#include<stdio.h>
main()
{
    unsigned char Val = 0xFF-15, Val2 = 0xFF;
    if (Val+16 < Val2)
    {
        printf("Val is less than Val2\n");
    }
}

Tengo dos preguntas:

  1. ¿El valor Val obtener promovido a tipo de datos alto cuando el tipo de datos no está firmado char?
  2. En caso afirmativo, ¿por qué no se promovió de 32 bits a 64 bits? unsigned long?

5
2018-04-24 14:26


origen


Respuestas:


El estándar C11 dice lo siguiente (C11 6.3.11p2.2):

Si una int puede representar todos los valores del tipo original (restringido por el ancho, para un campo de bits), el valor se convierte en int; de lo contrario, se convierte en un unsigned int. Estas se llaman promociones enteras. Todos los otros tipos no se modifican por las promociones enteras.

Así:

  1. unsigned char será promovido - sin embargo, es un detalle de implementación si int puede representar todos los valores de unsigned char - por lo que podría ser promovido a unsigned int en esas plataformas. La suya no es una de esas plataformas, por lo que su segunda comparación es (int)Val + 16 < (int)Val2.

  2. como dice la última oración del párrafo citado, una unsigned int nunca es promovido. Dado que la aritmética se realiza en ints sin signo en el primer fragmento, el resultado de 0xFFFFFFFF - 15 + 16 es 0U en una computadora con 32-value-bit unsigned int.


6
2018-04-24 14:40



Sí, en el segundo caso los números se promocionan a int. Si modificas tu código así:

#include<stdio.h>
int main()
{
    unsigned char Val = 0xFF-15, Val2 = 0xFF;
    if ((unsigned char)(Val+16) < Val2)
    {
        printf("Val is less than Val2\n");
    }
}

Obtendrás el comportamiento que esperas.


2
2018-04-24 14:42