liveBook · Manning

Function pointer type

As explained in Rust in Action: Systems programming concepts and techniques

A function pointer is a value that identifies a function and can be passed or stored so that the function can be invoked indirectly.

A function pointer identifies the start of a function’s executable code, rather than a data value. In Rust, a function’s signature describes its arguments and return value; for example, `fn() -> ()` takes no arguments and returns unit. The address can be passed to another component so it can call the function later. section 12.7.1 section 12.10

Listing 12.10 Casting a function to usize
fn noop() {}
 
fn main() {
  let fn_ptr = noop as usize;
  let typed_fn_ptr = noop as *const fn() -> ();
 
  println!("noop as usize:    0x{:x}", fn_ptr);
  println!("noop as *const T: {:p}", typed_fn_ptr);      #1
}

The `noop` example casts one function address to `usize` and to `*const fn() -> ()`. Both printed values identify the same location. The address will differ on your machine. section 12.7.1

Registering a signal handler

`libc::signal` associates a signal with a handler function. The handler has type `fn(i32) -> ()`, but this interface accepts an untyped pointer, so the example casts the handler to `usize`. When the signal arrives, the registered function runs; the handler keeps its work minimal by setting a shutdown flag for the main loop to check. section 12.6.2 section 12.12

A closure that captures variables is different: it has a compiler-generated type that contains values from its environment. A closure that captures nothing can also serve as a function pointer. Keep that distinction in mind when choosing a callback. section 10.3

How Rust in Action: Systems programming concepts and techniques covers it

How deep it goes
Explains executable-code addresses, pointer casts, and function signatures through small programs; does not develop a general callback API.
Examples
Uses an address-printing `noop` program and a `libc::signal` shutdown-handler program.
What it assumes
Assumes familiarity with basic Rust functions and pointers while explaining function addresses as executable bytes.
What you can do after
Apply it via `libc::signal` to register a handler and recognize why the example casts its function address.
How it connects
Connects function pointers to closures, callbacks, signal handlers, executable memory, and pointer casts.

Also explained in

Compare how 4 books explain function pointer type →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Rust in Action: Systems programming concepts and techniques. The section links point to the parts of the book it draws on.