For embedded code, why should I use "uint_t" types instead of "unsigned int"?
A standards-conforming compiler where int was anywhere from 17 to 32 bits may legitimately do anything it wants with the following code:

uint16_t x = 46341;
uint32_t y = x*x; // temp result is signed int, which can't hold 2147488281


An implementation that wanted to do so could legitimately generate a program that would do nothing except output the string "Fred" repeatedly on every port pin using every imaginable protocol.  The probability of a program getting ported to an implementation which would do such a thing is exceptionally low, but it is theoretically possible.  If want wanted to write the above code so that it would be guaranteed not to engage in Undefined Behavior, it would be necessary write the latter expression as (uint32_t)x*x or 1u*x*x.  On a compiler where int is between 17 and 31 bits, the latter expression would lop off the upper bits, but would not engage in Undefined Behavior.

I think the gcc warnings are probably trying to suggest that the code as written is not completely 100% portable.  There are times when code really should be written to avoid behaviors which would be Undefined on some implementations, but in many other cases one should simply figure that the code is unlikely to get used on implementations which would do overly annoying things.

Note that using types like int and short may eliminate some warnings and fix some problems, but would likely create others.  The interaction between types like uint16_t and C's integer-promotion rules are icky, but such types are still probably better than any alternative.