/// is deviated from.
/// - Lastly, there are multiple bit patterns that are considered NaN.
/// Rust does not currently guarantee that the bit patterns of NaN are
-/// preserved over arithmetic operations,
-/// so there may be some surprising results upon inspecting the bit patterns,
+/// preserved over arithmetic operations, and they are not guaranteed to be
+/// portable or even fully deterministic! This means that there may be some
+/// surprising results upon inspecting the bit patterns,
/// as the same calculations might produce NaNs with different bit patterns.
///
/// For more information on floating point numbers, see [Wikipedia][wikipedia].
/// is a reference to the function-specific ZST. `&bar` is basically never what you
/// want when `bar` is a function.
///
+/// ### Casting to and from integers
+///
+/// You cast function pointers directly to integers:
+///
+/// ```rust
+/// let fnptr: fn(i32) -> i32 = |x| x+2;
+/// let fnptr_addr = fnptr as usize;
+/// ```
+///
+/// However, a direct cast back is not possible. You need to use `transmute`:
+///
+/// ```rust
+/// # let fnptr: fn(i32) -> i32 = |x| x+2;
+/// # let fnptr_addr = fnptr as usize;
+/// let fnptr = fnptr_addr as *const ();
+/// let fnptr: fn(i32) -> i32 = unsafe { std::mem::transmute(fnptr) };
+/// assert_eq!(fnptr(40), 42);
+/// ```
+///
+/// Crucially, we `as`-cast to a raw pointer before `transmute`ing to a function pointer.
+/// This avoids an integer-to-pointer `transmute`, which can be problematic.
+/// Transmuting between raw pointers and function pointers (i.e., two pointer types) is fine.
+///
+/// Note that all of this is not portable to platforms where function pointers and data pointers
+/// have different sizes.
+///
/// ### Traits
///
/// Function pointers implement the following traits: