This is possible, but not advised. If you do this, you should cast the
int32 to an
int256 in order to be explicit.
int32 a = 1;
int256 b = 3;
int256 c = int256(a) + b;
However, using types smaller than 32 bytes may actually be more expensive than using types that are 32 bytes exactly (such as
uint256, etc.). The reason for this is that the EVM expects 32 bytes and has to do additional operations if it wants to operate on anything less.
From the docs:
When using elements that are smaller than 32 bytes, your contract’s gas usage may be higher. This is because the EVM operates on 32 bytes at a time. Therefore, if the element is smaller than that, the EVM must use more operations in order to reduce the size of the element from 32 bytes to the desired size.
It is only beneficial to use reduced-size arguments if you are dealing with storage values because the compiler will pack multiple elements into one storage slot, and thus, combine multiple reads or writes into a single operation. When dealing with function arguments or memory values, there is no inherent benefit because the compiler does not pack these values.
Finally, in order to allow the EVM to optimize for this, ensure that you try to order your storage variables and struct members such that they can be packed tightly. For example, declaring your storage variables in the order of uint128, uint128, uint256 instead of uint128, uint256, uint128, as the former will only take up two slots of storage whereas the latter will take up three.