-
Couldn't load subscription status.
- Fork 20
[Guideline] Add safe division guideline to avoid dividing by zero #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
[Guideline] Add safe division guideline to avoid dividing by zero #136
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.
| .. 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.
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'm unsure if multiple examples are allowed, but these are small and related so I just put both in one code block in 752ba7a
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.
We are still at the point where these things can be discussed. If we'd like to have a number of compliant and non-compliant examples, this is possible likely in Sphinx Needs. Opened #141 to track.
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.
Question to @vapdrs, @rcseacord, @felix91gr -- is this something which we think should be addressed as a blocking concern for this PR or mark this as resolved since we have #141 and move on for now?
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.
@PLeVasseur I would much prefer it if we had multiple examples, one for each specific case. Whenever I've read guidelines, having "atomic" (ie indivisible / minimal) examples has been essential for me to understand them quickly and without needing to ask for further help. I think we can benefit a lot if each example addresses a single concern.
So yeah, I think it's best if we block until we have this capability. Sorry, @vapdrs, I'm asking you to wait until we've sorted this
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.
No worries here. I don't mind waiting.
|
Resolves #20 |
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.
Hey @vapdrs -- appreciate this addition! I've left a few suggestions and comments
Co-authored-by: Pete LeVasseur <[email protected]>
Additionally the code block formatting was updating, and a link was added. Co-authored-by: Pete LeVasseur <[email protected]>
|
Damn, I thought the PR would fix itself after a non-conflicting change to Because when looking at this branch, the spec lock_file is outdated. @vapdrs can I ask you to re-merge the latest commits from With those changes, it should build and I'll be able to give a reasonable final review :3 |
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 hope I'm not boring you 🫶
This is mostly details - the content and structure itself all look good to me.
| The developer must explicitly indicate the intended behavior when a division by zero occurs, or use a | ||
| type for which it is invalid to have a value of zero. |
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.
Like in my first comment, I don't think the description here of "explicitly indicate the intended behavior" makes sense now that the PR is focusing uniquely on the division-by-zero scenario.
I'd also change the second point, since it's not that a NonZero<T> with an inner value of zero is invalid.
It's more like it's impossible to have a NonZero<T> with an inner value of zero - unless the user constructs one using unsafe and uses the unchecked_ constructor, which like everything regarding unsafe, probably merits its own entire guideline series. Though in that case, if the user does construct a NonZero<T> using a T of value zero through the unchecked_ method, that's Undefined Behavior.
Anyway. I'm thinking of something like this:
The developer must explicitly:
* Use checked division functions, which make sure a zero divisor is handled separately, or
* To first create divisors using :std:`std::num::NonZero`, which let the programmer prove the divisor is not zero.
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 agree, I rephrased the suggestion though
|
Something funny I just realized is that using Since in And since comparisons tend to be the most expensive of the basic CPU instructions... the big picture in performance is that Hm. I shall do some codegen testing, I guess. The alternative scenario is that the compiler can prove the divisor is not zero. In that case, the zero-check and panic branch can be elided from the Therefore... both are basically the same in performance, unless the programmer can prove their divisors are not zero using outside information (some domain-specific info the compiler cannot see). And if the programmer can prove their divisors to not be zero, then they could eek some more performance out of |
|
Indeed! Dividing by |
I added a small note to the Rationale about that as well |
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've finally learned how to suggest changes directly.
Just some polish and one typo :)
Spelling and word choice from review Co-authored-by: Félix Fischer <[email protected]>
Co-authored-by: Félix Fischer <[email protected]>
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.
Beyond these changes, I have nothing more to ask. The PR is done.
Great job, @vapdrs! And thank you for your patience :)
Co-authored-by: Félix Fischer <[email protected]>
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.
@vapdrs -- thanks for working with us as we reviewed
|
⛵ |
Add a new guidlelines disallowing ArithmeticExpressions to use integer divisors. This is the "MISRA" style counterpart to #132