-
Notifications
You must be signed in to change notification settings - Fork 16
[Guideline] Add checked arithmetic guidelines #136
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
✅ Deploy Preview for scrc-coding-guidelines ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
The |
These correspond to the unique ID's for each section.
This guideline applies when an ArithmeticExpression is used with operands whose types evaluates integer or | ||
floating-point types. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You know, I'm not sure floating-point types fit here.
- One one hand, the
f32
and other such types are defined to be compliant with a specific IEEE standard. - On the other hand, neither looking at that type's methods nor doing a search for
checked_
methods in stdlib I've been able to find anything like the safe/checked operations we have for integer types. I suspect they do not exist for floats.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This guideline applies when an ArithmeticExpression is used with operands whose types evaluates integer or | |
floating-point types. | |
This guideline applies when an `ArithmeticExpression` is used with operands of integer or | |
floating-point type. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I agree I would separate integer from floating point types.
.. rationale:: | ||
:id: rat_vLFlPWSCHRje | ||
:status: draft | ||
|
||
The built-in semantics for these expressions can result in panics, or silent wraparound when overflow, | ||
underflow, or division by zero occurs. It is better to explicitly declare what should happen during | ||
these events with checked arithmetic functions. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems perfect to me 👌
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Underflow is only a condition that occurs during floating point operations. Integers can only overflow. At least that's true in C.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.. rationale:: | |
:id: rat_vLFlPWSCHRje | |
:status: draft | |
The built-in semantics for these expressions can result in panics, or silent wraparound when overflow, | |
underflow, or division by zero occurs. It is better to explicitly declare what should happen during | |
these events with checked arithmetic functions. | |
.. rationale:: | |
:id: rat_vLFlPWSCHRje | |
:status: draft | |
The built-in semantics for these expressions can result in panics, or silent wraparound when overflow, | |
underflow, or division by zero errors. | |
Explicitly declare what should happen during using checked arithmetic functions. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Underflow is only a condition that occurs during floating point operations. Integers can only overflow. At least that's true in C.
I think that's true, but it's only true regarding the name – Underflow does occur in Rust, in the sense of attempting to go below the minimum value, but (I've just come to realize) we call it Overflow just the same.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Underflow is typically a floating point property. Floating point is really weird though because almost nothing is an error if you anticipate it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Floating point is really weird though because almost nothing is an error if you anticipate it.
I have so many questions. Though floating point handling and its semantics are outside the topic of this PR. I'd like to ask you about floats in the context of SC. Are you perchance in the rust-lang
Zulip?
.. non_compliant_example:: | ||
:id: non_compl_ex_0XeioBrgfh5z | ||
:status: draft | ||
|
||
When the division is performed, the right operand is evaluated to zero and the program panics. | ||
|
||
.. code-block:: rust | ||
let x = 0; | ||
let x = 5 / x; | ||
.. compliant_example:: | ||
:id: compl_ex_k1CD6xoZxhXb | ||
:status: draft | ||
|
||
If an overflow occurs, it is explicit that the addition should wrap. | ||
|
||
.. code-block:: rust | ||
let y = 135u8 | ||
let x = 200u8.wrapping_add(y); | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the document allowed to have more than one non-compliant and more than one compliant example?
Since this guideline covers both the divide-by-zero and the arithmetic-overflow cases, I think it's only natural that it would have an example for both :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you should have a compliant solution corresponding to each noncompliant example. For example, how do I deal with divide by zero on a compliant solution. Also show the incorrect version of the wrapping example.
:id: gui_mNEvznFjC3kG | ||
:category: advisory | ||
:status: draft | ||
:release: latest | ||
:fls: fls_Q9dhNiICGIfr | ||
:decidability: decidable | ||
:scope: module | ||
:tags: numerics | ||
|
||
This guideline applies to ArithmeticExpressions as well as any call to the integer or floating point type | ||
methods that begin with `unchecked_`. | ||
|
||
.. rationale:: | ||
:id: rat_7tF18FIwSYws | ||
:status: draft | ||
|
||
The built-in semantics for these expressions can result in panics, or silent wraparound when overflow, | ||
underflow, or division by zero occurs. It is better to explicitly declare what should happen during | ||
these events with checked arithmetic functions. | ||
|
||
.. non_compliant_example:: | ||
:id: non_compl_ex_JeRRIgVjq8IE | ||
:status: draft | ||
|
||
When the multiplication is performed, the evaluation could encounter wrapping or a panic that is not | ||
handled explicitly. | ||
|
||
.. code-block:: rust | ||
let x = 13u8.unchecked_mul(y); | ||
.. compliant_example:: | ||
:id: compl_ex_HIBS9PeBa41c | ||
:status: draft | ||
|
||
When the addition is performed, the overflow will be detected and the author will need to explicitly | ||
deal with the Option value returned. | ||
|
||
.. code-block:: rust | ||
let y = 135u8 | ||
let x = 200u8.checked_add(y); | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are many unchecked
functions in stdlib
. I reckon we might want to add a rule against all of them? I'm not sure. Some of them might be reasonable for SC contexts.
Regardless: just like for the rule above, the unchecked_
arithmetic functions mentioned here only exist for integer types. Floats do have a to_int_unchecked
method, though.
Resolves #20 |
Add two new guidlelines disallowing most ArithmeticExpressions and unchecked arithmetic. The reason there are two rules is such that if a project really needs the performance afforded by
unchecked_mul
, they can disregard the advisory rule and use the required one.