Estoy escribiendo una aplicación en c para un STM32F105, usando gcc.
En el pasado (con proyectos más simples), siempre he definido las variables como char
, int
, unsigned int
, etc.
Veo que es común usar los tipos definidos en stdint.h, como int8_t
, uint8_t
, uint32_t
, etc. Esto es cierto en las múltiples API que estoy usando, y también en el Biblioteca ARM CMSIS de ST.
Creo que entiendo por qué debemos hacerlo; para permitir que el compilador optimice mejor el espacio de memoria. Supongo que puede haber razones adicionales.
Sin embargo, debido a las reglas de promoción de enteros de c, me mantengo contra las advertencias de conversión cada vez que intento agregar dos valores, hacer una operación a nivel de bits, etc. La advertencia dice algo así como conversion to 'uint16_t' from 'int' may alter its value [-Wconversion]
. El problema se trata aquí y aquí .
No sucede cuando se utilizan variables declaradas como int
o unsigned int
.
Para dar un par de ejemplos, dado esto:
uint16_t value16;
uint8_t value8;
Tendría que cambiar esto:
value16 <<= 8;
value8 += 2;
a esto:
value16 = (uint16_t)(value16 << 8);
value8 = (uint8_t)(value8 + 2);
Es feo, pero puedo hacerlo si es necesario. Aquí están mis preguntas:
-
¿Hay un caso en el que la conversión de unsigned a firmada y volver a unsigned hará que el resultado sea incorrecto?
-
¿Existen otras razones importantes para el uso de los tipos enteros stdint.h?
Según las respuestas que estoy recibiendo, parece que generalmente se prefieren los tipos stdint.h, aunque c convierte uint
a int
y vuelve. Esto lleva a una pregunta más grande:
- Puedo evitar las advertencias del compilador mediante el uso de encasillamiento (por ejemplo,
value16 = (uint16_t)(value16 << 8);
). ¿Estoy ocultando el problema? ¿Hay una mejor manera de hacerlo?