| # Pointer types | |
| C++ defines two categories of pointer types, while Rust adds a third. They are: | |
| * Pointers to some (non-function) object, without lifetime information. C++ | |
| calls these | |
| [object pointers](https://en.cppreference.com/w/cpp/language/pointer#Pointers_to_objects), | |
| while Rust calls them | |
| [raw pointers](https://doc.rust-lang.org/reference/types/pointer.html#raw-pointers-const-and-mut). | |
| * Function pointers | |
| ([C++](https://en.cppreference.com/w/cpp/language/pointer#Pointers_to_functions), | |
| [Rust](https://doc.rust-lang.org/reference/types/function-pointer.html)). | |
| * Finally, Rust references: non-aliasing pointers with lifetime information. | |
| With the exception of [Rust references](#rust_references), which are only | |
| permitted in limited circumstances, pointer types are fully supported as long as | |
| the type they point to is supported. For example, `const int32_t*` maps | |
| bidirectionally to `*const i32`, and `void (*)(int32_t)` maps bidirectionally to | |
| `fn(i32)`. | |
| ## Object pointers {#object} | |
| An "object pointer" is the C++ terminology for any pointer that is not a | |
| function pointer. Rust would call these "raw pointers". These are mapped to each | |
| other bidirectionally: | |
| C++ | Rust | |
| ---------- | ---------- | |
| `const T*` | `*const T` | |
| `T*` | `*mut T` | |
| ### C++ pointers with lifetime {#object_lifetime} | |
| C++ allows attaching lifetime annotations to arbitrary types, including | |
| pointers. There are two competing annotations for this, neither of which are | |
| supported in Rust bindings yet: | |
| * `[[clang::lifetimebound]]` | |
| * [Lifetime attributes](https://discourse.llvm.org/t/rfc-lifetime-annotations-for-c/61377) | |
| ## Function pointers {#function} | |
| C++ function pointers map to Rust `extern "C" fn(...) -> ...` function pointers, | |
| and vice versa: | |
| C++ | Rust | |
| ------------------------------------- | ------------------------------- | |
| `void(&)(int32_t)>` | `extern "C" fn(i32)` | |
| `void(*)(int32_t)` | `Option<extern "C" fn(i32)>` | |
| `std::type_identity_t<void(int32_t)>` | Not supported [^function_types] | |
| If the corresponding C++ function definition would be `unsafe` in Rust (per the | |
| rules for [C++ function declarations](../cpp/functions.md#unsafe)), then so is | |
| the function pointer – for example, a C++ reference to `void(void*)` becomes a | |
| Rust `unsafe extern "C" fn(_: *mut c_void)`. | |
| Not all function pointers receive bindings. If the function cannot be called | |
| directly, due to a known or potential ABI mismatch between Rust and C++, then | |
| the function pointer receives no bindings. In particular, function pointers | |
| cannot take layout-compatible types by value. You can work around this by taking | |
| or returning such problematic types by pointer instead of by value. | |
| ### Lifetime {#function_lifetime} | |
| All function pointers are `'static`. | |
| There is no way to specify the lifetime of a function pointer in Rust, nor in | |
| C++: both assume a `'static` lifetime. In scenarios where the lifetime may be | |
| shorter than `'static` (e.g., JIT compilation, or dynamic loading and unloading | |
| of shared libraries at runtime), the developer is responsible for managing the | |
| lifetime of the function pointer. | |
| [^function_types]: C++ has plain | |
| [function types](https://en.cppreference.com/w/cpp/types/is_function): | |
| the type pointed to by function pointers. There is no Rust | |
| equivalent. However, since C++ functions implicitly coerce to | |
| function pointers, this only comes up in template classes | |
| like | |
| [`std::function`](https://en.cppreference.com/w/cpp/utility/functional/function) | |
| or | |
| [`absl::AnyInvocable`](https://github.com/abseil/abseil-cpp/blob/master/absl/functional/any_invocable.h). | |
| Or, in this case, `type_identity_t`. | |
| ## Rust references {#rust_references} | |
| Rust references, unlike C++ references, cannot mutably alias. This introduces a | |
| new form of Undefined Behavior (UB) that many C++ programmers may not be | |
| accustomed to. For now, C++ pointers and references do **not** map to Rust | |
| references. Instead, they map to Rust raw pointers. Vice versa, Rust references | |
| are an unsupported type which do not map to any C++ type at all. | |
| The one exception to this rule are function parameters. In some limited | |
| circumstances, Rust functions may accept references, and the corresponding C++ | |
| interface will accept C++ references. This is documented in | |
| <internal link>/rust/functions. |