mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Generate warning when rational numbers are converted to their mobile type without explicit requests
This commit is contained in:
@@ -26,6 +26,23 @@ except for comparison operators where the result is always ``bool``.
|
||||
The operators ``**`` (exponentiation), ``<<`` and ``>>`` use the type of the
|
||||
left operand for the operation and the result.
|
||||
|
||||
Ternary Operator
|
||||
----------------
|
||||
The ternary operator is used in expressions of the form ``<expression> ? <trueExpression> : <falseExpression>``.
|
||||
It evaluates one of the latter two given expressions depending upon the result of the evaluation of the main ``<expression>``.
|
||||
If ``<expression>`` evaluates to ``true``, then ``<trueExpression>`` will be evaluated, otherwise ``<falseExpression>`` is evaluated.
|
||||
|
||||
The result of the ternary operator does not have a rational number type, even if all of its operands are rational number literals.
|
||||
The result type is determined from the types of the two operands in the same way as above, converting to their mobile type first if required.
|
||||
|
||||
As a consequence, ``255 + (true ? 1 : 0)`` will revert due to arithmetic overflow.
|
||||
The reason is that ``(true ? 1 : 0)`` is of ``uint8`` type, which forces the addition to be performed in ``uint8`` as well,
|
||||
and 256 exceeds the range allowed for this type.
|
||||
|
||||
Another consequence is that an expression like ``1.5 + 1.5`` is valid but ``1.5 + (true ? 1.5 : 2.5)`` is not.
|
||||
This is because the former is a rational expression evaluated in unlimited precision and only its final value matters.
|
||||
The latter involves a conversion of a fractional rational number to an integer, which is currently disallowed.
|
||||
|
||||
.. index:: assignment, lvalue, ! compound operators
|
||||
|
||||
Compound and Increment/Decrement Operators
|
||||
|
||||
@@ -463,7 +463,7 @@ There is no additional semantic meaning added to a number literal containing und
|
||||
the underscores are ignored.
|
||||
|
||||
Number literal expressions retain arbitrary precision until they are converted to a non-literal type (i.e. by
|
||||
using them together with a non-literal expression or by explicit conversion).
|
||||
using them together with anything else than a number literal expression (like boolean literals) or by explicit conversion).
|
||||
This means that computations do not overflow and divisions do not truncate
|
||||
in number literal expressions.
|
||||
|
||||
@@ -471,6 +471,15 @@ For example, ``(2**800 + 1) - 2**800`` results in the constant ``1`` (of type ``
|
||||
although intermediate results would not even fit the machine word size. Furthermore, ``.5 * 8`` results
|
||||
in the integer ``4`` (although non-integers were used in between).
|
||||
|
||||
.. warning::
|
||||
While most operators produce a literal expression when applied to literals, there are certain operators that do not follow this pattern:
|
||||
|
||||
- Ternary operator (``... ? ... : ...``),
|
||||
- Array subscript (``<array>[<index>]``).
|
||||
|
||||
You might expect expressions like ``255 + (true ? 1 : 0)`` or ``255 + [1, 2, 3][0]`` to be equivalent to using the literal 256
|
||||
directly, but in fact they are computed within the type ``uint8`` and can overflow.
|
||||
|
||||
Any operator that can be applied to integers can also be applied to number literal expressions as
|
||||
long as the operands are integers. If any of the two is fractional, bit operations are disallowed
|
||||
and exponentiation is disallowed if the exponent is fractional (because that might result in
|
||||
|
||||
Reference in New Issue
Block a user