Skip to content

New lint: Performing arithmetic on numeric value of function pointer #9517

@Aaron1011

Description

@Aaron1011

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 u64

However, 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 u64

This 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-lintArea: New lints

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions