Skip to content

Commit 88cfa11

Browse files
authored
Update shifting operations guidelines in expressions.rst
Clarify rules for shifting operations in Rust, emphasizing the importance of using checked functions and addressing inconsistent behavior in different compilation modes.
1 parent 1b00276 commit 88cfa11

File tree

1 file changed

+10
-12
lines changed

1 file changed

+10
-12
lines changed

src/coding-guidelines/expressions.rst

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -795,7 +795,6 @@ Expressions
795795

796796
This rule applies to the following primitive types:
797797

798-
799798
* ``i8``
800799
* ``i16``
801800
* ``i32``
@@ -815,37 +814,36 @@ Expressions
815814

816815
This is a Subset rule, directly inspired by `INT34-C. Do not shift an expression by a negative number of bits or by greater than or equal to the number of bits that exist in the operand <https://wiki.sei.cmu.edu/confluence/x/ItcxBQ>`_.
817816

818-
In Rust these out-of-range shifts don't give rise to Undefined Behavior; however, they are still problematic in Safety Critical contexts for two reasons.
817+
Out-of-range shifts are not undefined behavior, but are problematic for the following reasons:
819818

820819

821820
*
822-
**Reason 1: inconsistent behavior**
821+
**Inconsistent behavior**
823822

824-
The behavior of shift operations depends on the compilation mode. Say for example, that we have a number ``x`` of type ``uN``\ , and we perform the operation
823+
The behavior of shift operations depends on the compilation mode.
824+
A shift of an unsigned integer value ``x`` by ``M`` positions:
825825

826-
``x << M``
826+
``x << M // left shift``
827+
``x >> M // right shift``
827828

828-
Then, it will behave like this:
829+
has the following behavior:
829830

830831
+------------------+-----------------+-----------------------+-----------------------+
831832
| Compilation Mode | ``0 <= M < N`` | ``M < 0`` | ``N <= M`` |
832833
+==================+=================+=======================+=======================+
833-
| Debug | Shifts normally | Panics | Panics |
834+
| Debug | Shifts ``M`` positions | Panics | Panics |
834835
+------------------+-----------------+-----------------------+-----------------------+
835-
| Release | Shifts normally | Shifts by ``M mod N`` | Shifts by ``M mod N`` |
836+
| Release | Shifts ``M`` positions | Shifts by ``M mod N`` | Shifts by ``M mod N`` |
836837
+------------------+-----------------+-----------------------+-----------------------+
837838

838839
..
839840
840-
Note: the behavior is exactly the same for the ``>>`` operator.
841-
842-
843841
Panicking in ``Debug`` is an issue by itself, however, a perhaps larger issue there is that its behavior is different from that of ``Release``. Such inconsistencies aren't acceptable in Safety Critical scenarios.
844842

845843
Therefore, a consistently-behaved operation should be required for performing shifts.
846844

847845
*
848-
**Reason 2: programmer intent**
846+
**Programmer intent**
849847

850848
There is no scenario in which it makes sense to perform a shift of negative length, or of more than ``N - 1`` bits. The operation itself becomes meaningless.
851849

0 commit comments

Comments
 (0)