0

What is the proper way to pass around named functions as function pointers?

static mut foo: *mut fn(buf: Vec<u8>) = 0 as *mut fn(buf: Vec<u8>);


fn main() {
    bar(&mut baz);
}

fn bar(f: &mut fn(buf: Vec<u8>)) {
    unsafe { foo = f };
}

fn baz(buf: Vec<u8>) {}

Produces:

error: mismatched types [--explain E0308]
 --> <anon>:5:9
  |>
5 |>     bar(&mut baz);
  |>         ^^^^^^^^ expected fn pointer, found fn item
note: expected type '&mut fn(std::vec::Vec<u8>)'
note:    found type '&mut fn(std::vec::Vec<u8>) {baz}'
nathansizemore
  • 3,028
  • 7
  • 39
  • 63
  • 1
    `bar(&mut (baz as fn(Vec)))` – Shepmaster Aug 22 '16 at 01:27
  • 1
    See [here](http://stackoverflow.com/questions/28151073/how-can-i-store-function-pointers-in-an-array), too. Also: why do you need a `*mut fn`? Are you really sure you need a mutable function pointer? Such that you can write where the assembly of the function lives? And please consider using an `Option` instead of casting `0` to a pointer. It won't decrease performance or memory usage. – Lukas Kalbertodt Aug 22 '16 at 01:28
  • @LukasKalbertodt There definitely is a [difference](https://play.rust-lang.org/?gist=a89345544897b3cba84b669d8a7da2c3&version=stable&backtrace=0). Also, yes - that is the reason I want a `*mut fn`. – nathansizemore Aug 22 '16 at 02:27
  • 1
    And to double check, you already know why static mutable variables are `unsafe` and thus why they are a bad idea? – Shepmaster Aug 22 '16 at 02:32
  • @Shepmaster Sure. I gain a constant mem address with static, and because of that not being inlined, the borrow checker can't reason about it. As a blanket statement, unsafe == bad idea is a bit of an over statement. If I planned on having concurrent mutable access, of course there'd be a `Mutex` around it :) – nathansizemore Aug 22 '16 at 02:49
  • 2
    @LukasKalbertodt a `*mut fn()` is not a mutable function pointer - `fn()` is itself a function pointer, so `*mut fn()` is a raw mutable pointer to a function pointer. Simply use `fn()` when you need a function pointer, and if you are writing to it (assuming you have done the due diligence to be able to write to that region of memory, and that casting function pointers to data pointers is valid on your platform), just cast the `fn()` to a `*mut u8` or whatever you need to write to it. – SpaceManiac Aug 22 '16 at 09:10

0 Answers0