2.13 Conversions
Every programming language that supports different types supports the concept of conversions, where variables of different types can be converted between each other. Conversions have been mentioned earlier, here we will dive deep into them. There are two types of these conversions.
Implicit Conversions
These conversions happen implicitly: the conversion is applied by the compiler itself. These typically happen where that conversion makes sense semantically and there is no information that is lost, so this is a very safe conversion applied by the compiler. Such conversions happen during assignments of variables when variables are passed as arguments to functions, and the parameter types of those functions are of a different type than the arguments applied (and in other contexts as well).
Examples of implicit conversions in the case of Solidity
are converting a uint8
to uint16
or uint128
to uint256
and so on, where the resulting type is bigger in the sense of the storage supported than the type that is being converted from.
So uint16
has 16 bits that can safely store uint8
. However exceptions to implicit conversions are converting from signed integers to unsigned integers, and that doesn't make semantic sense because unsigned integers cannot hold or represent negative values.
Explicit Conversions
The flip side of implicit conversion are explicit conversions, where the type conversions are explicitly applied by the developers themselves and not by the compiler. The reason for that is the compiler cannot deduce or prove the type safety of such conversions and they may result in an unexpected behavior.
There are various rules to such explicit conversions: in the case of integers when they are converted to a smaller type, the higher order bits are cut off when they are converted to a larger type they are padded on the left with the higher order end.
So these apply for example when a uint8
is converted to uint16
the padding happens on to the left and when a uint16
is converted to uint8
, the higher order bits are cut off. Similarly for fixed size bytes, the bytes
arrays or bytes1
all the way to bytes32
, converting to a smaller type cuts off bytes to the right and converting to a larger type will pad bytes to the right.
So these rules are something that the developer has to pay attention to when forcing explicit conversions and if not done right, they could really result in undefined unexpected behavior, because the values underlying variables are chopped off in an unexpected fashion.
Literals Conversions
There are various rules that apply to these conversions. Decimals and hexadecimal number literals can be converted implicitly to any integer type that's large enough to represent it without getting it truncated. However decimal number literals cannot be implicitly converted to fixed size byte arrays.
Hexadecimal number literals can be converted to fixed size byte arrays but only if the number of hex digits fits the size of the bytes type exactly, although there are some exceptions to this. As well string literals and hex string literals can be implicitly converted to fixed size bite arrays, but only if the number of characters matches the size of the bytes
type.
So these are various Solidity
rules that need to be considered while converting literals and again it's something that you might encounter while analyzing smart contracts.
Last updated