mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	Extend documentation about explicit and implicit conversions between (u)intXX, bytesYY and literals.
This commit is contained in:
		
							parent
							
								
									cc54f6c425
								
							
						
					
					
						commit
						4f3f4a916b
					
				| @ -446,6 +446,25 @@ does not fit inside this range, it is truncated. These truncations can have | |||||||
| above is necessary to avoid certain attacks. | above is necessary to avoid certain attacks. | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | Why are explicit conversions between fixed-size bytes types and integer types failing? | ||||||
|  | ====================================================================================== | ||||||
|  | 
 | ||||||
|  | Since version 0.5.0 explicit conversions between fixed-size byte arrays and integers are only allowed, | ||||||
|  | if both types have the same size. This prevents unexpected behaviour when truncating or padding. | ||||||
|  | Such conversions are still possible, but intermediate casts are required that make the desired | ||||||
|  | truncation and padding convention explicit. See :ref:`types-conversion-elementary-types` for a full | ||||||
|  | explanation and examples. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | Why can number literals not be converted to fixed-size bytes types? | ||||||
|  | =================================================================== | ||||||
|  | 
 | ||||||
|  | Since version 0.5.0 only hexadecimal number literals can be converted to fixed-size bytes | ||||||
|  | types and only if the number of hex digits matches the size of the type. See :ref:`types-conversion-literals` | ||||||
|  | for a full explanation and examples. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| More Questions? | More Questions? | ||||||
| =============== | =============== | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1004,6 +1004,8 @@ It is important to note that ``delete a`` really behaves like an assignment to ` | |||||||
| 
 | 
 | ||||||
| .. index:: ! type;conversion, ! cast | .. index:: ! type;conversion, ! cast | ||||||
| 
 | 
 | ||||||
|  | .. _types-conversion-elementary-types: | ||||||
|  | 
 | ||||||
| Conversions between Elementary Types | Conversions between Elementary Types | ||||||
| ==================================== | ==================================== | ||||||
| 
 | 
 | ||||||
| @ -1017,9 +1019,7 @@ is possible if it | |||||||
| makes sense semantically and no information is lost: ``uint8`` is convertible to | makes sense semantically and no information is lost: ``uint8`` is convertible to | ||||||
| ``uint16`` and ``int128`` to ``int256``, but ``int8`` is not convertible to ``uint256`` | ``uint16`` and ``int128`` to ``int256``, but ``int8`` is not convertible to ``uint256`` | ||||||
| (because ``uint256`` cannot hold e.g. ``-1``). | (because ``uint256`` cannot hold e.g. ``-1``). | ||||||
| Furthermore, unsigned integers can be converted to bytes of the same or larger | Any integer type that can be converted to ``uint160`` can also be converted to ``address``. | ||||||
| size, but not vice-versa. Any type that can be converted to ``uint160`` can also |  | ||||||
| be converted to ``address``. |  | ||||||
| 
 | 
 | ||||||
| Explicit Conversions | Explicit Conversions | ||||||
| -------------------- | -------------------- | ||||||
| @ -1038,17 +1038,90 @@ a negative ``int8`` to a ``uint``: | |||||||
| At the end of this code snippet, ``x`` will have the value ``0xfffff..fd`` (64 hex | At the end of this code snippet, ``x`` will have the value ``0xfffff..fd`` (64 hex | ||||||
| characters), which is -3 in the two's complement representation of 256 bits. | characters), which is -3 in the two's complement representation of 256 bits. | ||||||
| 
 | 
 | ||||||
| If a type is explicitly converted to a smaller type, higher-order bits are | If an integer is explicitly converted to a smaller type, higher-order bits are | ||||||
| cut off:: | cut off:: | ||||||
| 
 | 
 | ||||||
|     uint32 a = 0x12345678; |     uint32 a = 0x12345678; | ||||||
|     uint16 b = uint16(a); // b will be 0x5678 now |     uint16 b = uint16(a); // b will be 0x5678 now | ||||||
| 
 | 
 | ||||||
| Since 0.5.0 explicit conversions between integers and fixed-size byte arrays | If an integer is explicitly converted to a larger type, it is padded on the left (i.e. at the higher order end). | ||||||
| are only allowed, if both have the same size. To convert between integers and | The result of the conversion will compare equal to the original integer. | ||||||
| fixed-size byte arrays of different size, they first have to be explicitly |  | ||||||
| converted to a matching size. This makes alignment and padding explicit:: |  | ||||||
| 
 | 
 | ||||||
|     uint16 x = 0xffff; |     uint16 a = 0x1234; | ||||||
|     bytes32(uint256(x)); // pad on the left |     uint32 b = uint32(a); // b will be 0x00001234 now | ||||||
|     bytes32(bytes2(x)); // pad on the right |     assert(a == b); | ||||||
|  | 
 | ||||||
|  | Fixed-size bytes types behave differently during conversions. They can be thought of as | ||||||
|  | sequences of individual bytes and converting to a smaller type will cut off the | ||||||
|  | sequence:: | ||||||
|  | 
 | ||||||
|  |     bytes2 a = 0x1234; | ||||||
|  |     bytes1 b = bytes1(a); // b will be 0x12 | ||||||
|  | 
 | ||||||
|  | If a fixed-size bytes type is explicitly converted to a larger type, it is padded on | ||||||
|  | the right. Accessing the byte at a fixed index will result in the same value before and | ||||||
|  | after the conversion (if the index is still in range):: | ||||||
|  | 
 | ||||||
|  |     bytes2 a = 0x1234; | ||||||
|  |     bytes4 b = bytes4(a); // b will be 0x12340000 | ||||||
|  |     assert(a[0] == b[0]); | ||||||
|  |     assert(a[1] == b[1]); | ||||||
|  | 
 | ||||||
|  | Since integers and fixed-size byte arrays behave differently when truncating or | ||||||
|  | padding, explicit conversions between integers and fixed-size byte arrays are only allowed, | ||||||
|  | if both have the same size. If you want to convert between integers and fixed-size byte arrays of | ||||||
|  | different size, you have to use intermediate conversions that make the desired truncation and padding | ||||||
|  | rules explicit:: | ||||||
|  | 
 | ||||||
|  |     bytes2 a = 0x1234; | ||||||
|  |     uint32 b = uint16(a); // b will be 0x00001234 | ||||||
|  |     uint32 c = uint32(bytes4(a)); // c will be 0x12340000 | ||||||
|  |     uint8 d = uint8(uint16(a)); // d will be 0x34 | ||||||
|  |     uint8 e = uint8(bytes1(a)); // d will be 0x12 | ||||||
|  | 
 | ||||||
|  | .. _types-conversion-literals: | ||||||
|  | 
 | ||||||
|  | Conversions between Literals and Elementary Types | ||||||
|  | ================================================= | ||||||
|  | 
 | ||||||
|  | Integer Types | ||||||
|  | ------------- | ||||||
|  | 
 | ||||||
|  | Decimal and hexadecimal number literals can be implicitly converted to any integer type | ||||||
|  | that is large enough to represent it without truncation:: | ||||||
|  | 
 | ||||||
|  |     uint8 a = 12; // fine | ||||||
|  |     uint32 b = 1234; // fine | ||||||
|  |     uint16 c = 0x123456; // fails, since it would have to truncate to 0x3456 | ||||||
|  | 
 | ||||||
|  | Fixed-Size Byte Arrays | ||||||
|  | ---------------------- | ||||||
|  | 
 | ||||||
|  | Decimal number literals cannot be implicitly converted to fixed-size byte arrays. Hexadecimal | ||||||
|  | number literals can be, but only if the number of hex digits exactly fits the size of the bytes | ||||||
|  | type. As an exception both decimal and hexadecimal literals which have a value of zero can be | ||||||
|  | converted to any fixed-size bytes type:: | ||||||
|  | 
 | ||||||
|  |     bytes2 a = 54321; // not allowed | ||||||
|  |     bytes2 b = 0x12; // not allowed | ||||||
|  |     bytes2 c = 0x123; // not allowed | ||||||
|  |     bytes2 d = 0x1234; // fine | ||||||
|  |     bytes2 e = 0x0012; // fine | ||||||
|  |     bytes4 f = 0; // fine | ||||||
|  |     bytes4 g = 0x0; // fine | ||||||
|  | 
 | ||||||
|  | String literals and hex string literals can be implicitly converted to fixed-size byte arrays, | ||||||
|  | if their number of characters matches the size of the bytes type:: | ||||||
|  | 
 | ||||||
|  |     bytes2 a = hex"1234"; // fine | ||||||
|  |     bytes2 b = "xy"; // fine | ||||||
|  |     bytes2 c = hex"12"; // not allowed | ||||||
|  |     bytes2 d = hex"123"; // not allowed | ||||||
|  |     bytes2 e = "x"; // not allowed | ||||||
|  |     bytes2 f = "xyz"; // not allowed | ||||||
|  | 
 | ||||||
|  | Addresses | ||||||
|  | --------- | ||||||
|  | 
 | ||||||
|  | As described in :ref:`address_literals`, hex literals of the correct size that pass the checksum | ||||||
|  | test are of ``address`` type. No other literals can be implicitly converted to the ``address`` type. | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user