I am writing an application in c for an STM32F105, using gcc.
In the past (with simpler projects), I have always defined variables as char
, int
, unsigned int
, and so on.
I see that it is common to use the types defined in stdint.h, such as int8_t
, uint8_t
, uint32_t
, etc. This it true in multiple API's that I am using, and also in the ARM CMSIS library from ST.
I believe that I understand why we should do so; to allow the compiler to better optimize memory space. I expect there may be additional reasons.
However, because of c's integer promotion rules, I keep running up against conversion warnings any time I try to add two values, do a bitwise operation, etc. The warning reads something like conversion to 'uint16_t' from 'int' may alter its value [-Wconversion]
. The issue is discussed here and here.
It doesn't happen when using variables declared as int
or unsigned int
.
To give a couple of examples, given this:
uint16_t value16;
uint8_t value8;
I would have to change this:
value16 <<= 8;
value8 += 2;
to this:
value16 = (uint16_t)(value16 << 8);
value8 = (uint8_t)(value8 + 2);
It's ugly, but I can do it if necessary. Here are my questions:
Is there a case where the conversion from unsigned to signed and back to unsigned will make the result incorrect?
Are there any other big reasons for/against using the stdint.h integer types?
Based on the answers I'm receiving, it looks like the stdint.h types are generally preferred, even though c converts uint
to int
and back. This leads to a bigger question:
- I can prevent the compiler warnings by using typecasting (e.g.
value16 = (uint16_t)(value16 << 8);
). Am I just hiding the problem? Is there a better way to go about it?
8u
and2u
. \$\endgroup\$value8 += 2u;
andvalue8 = value8 + 2u;
, but I get the same warnings. \$\endgroup\$