First, here is what I understand and think what is true for the question.
Use fast data types for single variables like counters or for
loop indexe
Writing highly portable code is hard. Writing highly portable code that is optimal and works correctly is even harder.
For the majority of time, if it is feasible, I would suggest using basic types such as int
, char
, etc, rather than uint8_t
or uint8_fast_t
. The types int
and char
is guaranteed to exist. There is no doubt about that. Of course, SOMETIMES we need a specific behaviour from the code, and that will require a specific type - but that code will most likely break if the system doesn't support that exact type.
For your first example, it is extremely unlikely that you'll get better performance than using int
, unless your code is designed to (also) run on 8-bit processors. On a 16-, 32- or 64-bit processor, the native size will be the fastest for loops (unsigned being slightly better on 64-bit machines, since it doesn't require sign extension).
In your second example, it really only matters if the array is large enough to warrant the space-saving over using either char
or int
or short
or whatever makes sense for the content. On modern machines (including many embedded platforms and even when usign the stack) 400 bytes isn't really that much.
For your third example, obviously, for protocols, you will need to use types that match the protocol definition exactly, or things will go wrong. On platforms that doesn't support the correct type, this will have to be solved in some platform specific way - how you go about it will depend on exactly what the platform actually supports.
So, to answer your concrete questions:
Excessive use of "special type" variables is likely to:
Remember also that performance is often a case of 90% of the time is taken by 10% of the code. Understanding where (under normal usage) your code spends its time is critical. Of course, when porting code to different systems and on different architectures, you may find that the performance bottleneck moves, based on the relationship between processor speed, size of caches and memory speed. A system with high processor speed, but (realtively) small caches can sometimes perform worse than a similar system with lower clock-speed and bigger caches, just as one example.