Cita de: Xafi en 7 Julio 2013, 02:21 AMtypedef unsigned int UintNo. La ultima asignación es valida (operaciones de ese tipo pueden causar un verdadero dolor de cabeza).
Uint x=5;//Bien
Uint x= -1; Mal solo acepta positivos.
Ello porque si un valor esta fuera del rango valido (tipo entero sin signo) a este se le suma (o resta, dependiendo del caso) MAX + 1 hasta que este en el rango valido.
Por cierto el ejemplo que pones es la forma usual para calcular el valor máximo sin tener que utilizar el encabezado <limits.h>. Un ejemplo:
Código (c) [Seleccionar]
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
int main(void)
{
/* Imprime el valor maximo para el tipo unsigned int */
printf("%u\n", (unsigned) -1);
printf("%u\n", UINT_MAX);
/* Imprime el valor maximo para el tipo unsigned long */
printf("%lu\n", (unsigned long) -1);
printf("%lu\n", ULONG_MAX);
return EXIT_SUCCESS;
}
Otro escenario problemático son las expresiones donde se utilizan valores de tipo signed y unsigned. Por ejemplo este programa en C:
Código (c) [Seleccionar]
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int a = -1;
int b = 0;
unsigned x = 0;
printf("%d < %d ? %s\n", a, b, a < b ? "Si" : "No");
printf("%d < %uU ? %s\n", a, x, a < x ? "Si" : "No");
return EXIT_SUCCESS;
}
Genera la salida:
Código [Seleccionar]
-1 < 0 ? Si
-1 < 0U ? No
Ello porque los operandos de un operador binario deben ser del mismo tipo, en este caso el valor -1 de tipo signed int se convierte automáticamente al tipo unsigned int resultando en el valor mencionado (el máximo) y solo entonces se realiza la comparación.
Y si bien un compilador en modo estricto puede generar un mensaje de advertencia al compilar ese programa (o uno similar) ello no esta garantizado (y a veces uno las desactiva al saber que son inocuas).
Un saludo