When choosing an integer data type for your variables, the generally held view is that the smaller the type, the more efficient the code; however, this is only part of the story and smaller types are often not the best choice.
Each C compiler specifies the size of the (signed/unsigned) int type so that such values can be efficiently manipulated. This size will typically reflect the native data width of the target device and is usually the width of the device’s data registers. As a result, variables defined with either int type can be easily accessed and manipulated. Variables defined with a type smaller than an int (e.g. char variables) use less RAM to store, but accessing them might require extra instructions to extend the smaller values into a register before they can be used. So, you should use the int type in preference to smaller integer types, unless the size of your data must be strictly limited. And just for reference, the int type when using the MPLAB® XC16 Compiler is 16 bits wide; and it is 32 bits wide when using XC32.
However, there is a catch. The devices targeted by XC8 are 8-bit devices, and you might expect, therefore, that an int type on this compiler would be 8-bits wide. That would normally be the case, except that the C standard mandates that an int must be at least 16 bits wide. So, the int type with this compiler is 16-bits wide and is not the most efficient for handling small values. You are better choosing a char type, if it can hold all the values you require.
The contradictory type preferences imposed by all these compilers appear to create a dilemma if you need code to be portable across devices, so what should you do?
When defining integer variables, use the fastest minimum-width integer types provided by <stdint.h>, and don’t make assumptions about which type will produce the smallest or fastest code. For example if you need a variable that can hold an 8-bit quantity, make it either of the int_fast8_t or uint_fast8_t types. If you need a variable that can hold a 16-bit quantity, use either of the int_fast16_t or uint_fast16_t types, etc. The compiler will define these types appropriately and ensure that your code is compact and runs as fast as possible, regardless of which device you are targeting.