-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Description
What it does
This lints on any expression of the form some_arithmetic_expr(function_pointer as NumericType, other_type).
For example (note the lack of parenthesis - all of the function used here are function pointers)
let alloc_size: u64 = std::mem::size_of::<f32> as u64 * 5u64;
let extra_space: u32 = 1 + std::mem::size_of::<char> as u32;Lint Name
function_pointer_arithmetic
Category
correctness
Advantage
Performing arithmetic on a function pointer value (cast as a numeric type) is virtually never correct. Rust provides no guarantees about the relative location of functions in memory, or the actual in-memory assembly code at a function's address. In particular, multiplying or dividing by a pointer value is completely meaningless.
Drawbacks
None
Example
When writing low-level code, it's often useful to calculate sizes by multiplying by std::mem::size_of::<SomeType>. For example:
let alloc_size: u64 = num_elements * std::mem::size_of::<MyType>() as u64However, Rust allows casting a function pointer to any numeric type. If you accidentally commit the parenthesis in the function call, you'll obtain the following valid code:
let alloc_size: u64 = num_elements * std::mem::size_of::<MyType> as u64This multiplies a function address by num_elements, which is completely useless. The overall result will be completely unrelated to the size of MyType (and depending on the address of std::mem::size_of::<MyType>, it may also be very large). The code looks almost identical to the correct version, which could make it very difficult to notice the cause of the incorrect value.