Skip to content

Commit 8aaddc2

Browse files
Gaelanjiangliu
authored andcommitted
Correct docs for Address::unchecked_* methods.
The "unchecked" arithmatic methods on the Address trait were documented to cause undefined behavior in the case of overflow or underflow. This is a strange claim; if that were truly the case, the methods should have been unsafe. It wasn't, though; every existing implementation of the trait used the impl_address_ops! macro, which just implements them with the standard Rust arithmatic operators, which follow this well-defined behavior: - In debug mode, overflow is checked for and results in a panic. - In release mode, overflow results in silent wrapping. The wrapping behavior may be surprising or result in incorrect behavior, but it isn't undefined - we know exactly what will happen, and the optimizer is required to preserve that - so we shouldn't call it undefined. It's also worth nothing that the names of these methods are a little confusing - the integer types in std have unchecked_* methods that actually invoke UB on overflow (and, accordingly, are unsafe). It might be worth renaming these methods to something more consistent with std's naming. This is slightly complicated by the fact that std doesn't actually have a name for this behavior; it's just what the unqualified + operator or .add() method does. We may not want that, though, if we're trying to be more careful about overflow. In any case, we don't have to know how it should work to document the current behavior. Signed-off-by: Gaelan Steele <[email protected]>
1 parent 9070fb5 commit 8aaddc2

File tree

1 file changed

+15
-3
lines changed

1 file changed

+15
-3
lines changed

src/address.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,11 @@ pub trait Address:
9090

9191
/// Computes the offset from this address to the given base address.
9292
///
93-
/// Results in undefined behavior when an underflow occurs.
93+
/// In the event of overflow, follows standard Rust behavior, i.e. panic in debug builds,
94+
/// silently wrap in release builds.
95+
///
96+
/// Note that, unlike the `unchecked_*` methods in std, this method never invokes undefined
97+
/// behavior.
9498
/// # Examples
9599
///
96100
/// ```
@@ -131,7 +135,11 @@ pub trait Address:
131135

132136
/// Computes `self + offset`.
133137
///
134-
/// Results in undefined behavior when an overflow occurs.
138+
/// In the event of overflow, follows standard Rust behavior, i.e. panic in debug builds,
139+
/// silently wrap in release builds.
140+
///
141+
/// Note that, unlike the `unchecked_*` methods in std, this method never invokes undefined
142+
/// behavior..
135143
fn unchecked_add(&self, offset: Self::V) -> Self;
136144

137145
/// Subtracts two addresses, checking for underflow. If underflow happens, `None` is returned.
@@ -146,7 +154,11 @@ pub trait Address:
146154

147155
/// Computes `self - other`.
148156
///
149-
/// Results in undefined behavior when an underflow occurs.
157+
/// In the event of underflow, follows standard Rust behavior, i.e. panic in debug builds,
158+
/// silently wrap in release builds.
159+
///
160+
/// Note that, unlike the `unchecked_*` methods in std, this method never invokes undefined
161+
/// behavior.
150162
fn unchecked_sub(&self, other: Self::V) -> Self;
151163
}
152164

0 commit comments

Comments
 (0)