Estoy escribiendo una aplicación en c para un STM32F105, usando gcc.
En el pasado (con proyectos más simples), siempre me he definido como variables char
, int
, unsigned int
, y así sucesivamente.
Veo que es común el uso de los tipos definidos en stdint.h, como por ejemplo int8_t
, uint8_t
, uint32_t
, etc. Esto es cierto en múltiples API de que estoy usando, y también en la biblioteca de ARM CMSIS de ST.
Creo que entiendo por qué deberíamos hacerlo; para permitir que el compilador optimice mejor el espacio de memoria. Espero que pueda haber razones adicionales.
Sin embargo, debido a las reglas de promoción de enteros de c, sigo encontrándome con advertencias de conversión cada vez que trato de agregar dos valores, hacer una operación bit a bit, etc. La advertencia dice algo así conversion to 'uint16_t' from 'int' may alter its value [-Wconversion]
. El tema se discute aquí y aquí .
No sucede cuando se usan 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 algún caso en el que la conversión de sin signo a firmado y de regreso a sin signo hará que el resultado sea incorrecto?
¿Hay alguna otra razón importante a favor / en contra del uso de los tipos enteros stdint.h?
Según las respuestas que recibo, parece que generalmente se prefieren los tipos stdint.h, aunque c se convierte de un lado uint
a int
otro. Esto lleva a una pregunta más grande:
- Puedo evitar las advertencias del compilador usando la conversión de texto (por ejemplo
value16 = (uint16_t)(value16 << 8);
). ¿Solo estoy ocultando el problema? ¿Hay una mejor manera de hacerlo?
value8 += 2u;
y value8 = value8 + 2u;
, pero recibo las mismas advertencias.
8u
y2u
.