@@ -1060,6 +1060,8 @@ mod prim_ref {}
1060
1060
/// not be null, so if you want to pass a function pointer over FFI and be able to accommodate null
1061
1061
/// pointers, make your type `Option<fn()>` with your required signature.
1062
1062
///
1063
+ /// ### Safety
1064
+ ///
1063
1065
/// Plain function pointers are obtained by casting either plain functions, or closures that don't
1064
1066
/// capture an environment:
1065
1067
///
@@ -1097,23 +1099,60 @@ mod prim_ref {}
1097
1099
/// let really_safe_ptr: unsafe fn(usize) -> usize = add_one;
1098
1100
/// ```
1099
1101
///
1100
- /// On top of that, function pointers can vary based on what ABI they use. This is achieved by
1101
- /// adding the `extern` keyword to the type name, followed by the ABI in question. For example,
1102
- /// `fn()` is different from `extern "C" fn()`, which itself is different from `extern "stdcall"
1103
- /// fn()`, and so on for the various ABIs that Rust supports. Non-`extern` functions have an ABI
1104
- /// of `"Rust"`, and `extern` functions without an explicit ABI have an ABI of `"C"`. For more
1105
- /// information, see [the nomicon's section on foreign calling conventions][nomicon-abi].
1102
+ /// ### ABI
1103
+ ///
1104
+ /// On top of that, function pointers can vary based on what ABI they use. This
1105
+ /// is achieved by adding the `extern` keyword before the type, followed by the
1106
+ /// ABI in question. The default ABI is "Rust", i.e., `fn()` is the exact same
1107
+ /// type as `extern "Rust" fn()`. A pointer to a function with C ABI would have
1108
+ /// type `extern "C" fn()`.
1109
+ ///
1110
+ /// `extern "ABI" { ... }` blocks declare functions with ABI "ABI". The default
1111
+ /// here is "C", i.e., functions declared in an `extern {...}` block have "C"
1112
+ /// ABI.
1113
+ ///
1114
+ /// For more information and a list of supported ABIs, see [the nomicon's
1115
+ /// section on foreign calling conventions][nomicon-abi].
1106
1116
///
1107
- /// [nomicon-abi]: ../nomicon/ffi.html#foreign-calling-conventions
1117
+ /// ### Variadic functions
1108
1118
///
1109
1119
/// Extern function declarations with the "C" or "cdecl" ABIs can also be *variadic*, allowing them
1110
- /// to be called with a variable number of arguments. Normal rust functions, even those with an
1120
+ /// to be called with a variable number of arguments. Normal Rust functions, even those with an
1111
1121
/// `extern "ABI"`, cannot be variadic. For more information, see [the nomicon's section on
1112
1122
/// variadic functions][nomicon-variadic].
1113
1123
///
1114
1124
/// [nomicon-variadic]: ../nomicon/ffi.html#variadic-functions
1115
1125
///
1116
- /// These markers can be combined, so `unsafe extern "stdcall" fn()` is a valid type.
1126
+ /// ### Creating function pointers
1127
+ ///
1128
+ /// When `bar` is the name of a function, then the expression `bar` is *not* a
1129
+ /// function pointer. Rather, it denotes a value of an unnameable type that
1130
+ /// uniquely identifies the function `bar`. The value is zero-sized because the
1131
+ /// type already identifies the function. This has the advantage that "calling"
1132
+ /// the value (it implements the `Fn*` traits) does not require dynamic
1133
+ /// dispatch.
1134
+ ///
1135
+ /// This zero-sized type *coerces* to a regular function pointer. For example:
1136
+ ///
1137
+ /// ```rust
1138
+ /// use std::mem;
1139
+ ///
1140
+ /// fn bar(x: i32) {}
1141
+ ///
1142
+ /// let not_bar_ptr = bar; // `not_bar_ptr` is zero-sized, uniquely identifying `bar`
1143
+ /// assert_eq!(mem::size_of_val(¬_bar_ptr), 0);
1144
+ ///
1145
+ /// let bar_ptr: fn(i32) = not_bar_ptr; // force coercion to function pointer
1146
+ /// assert_eq!(mem::size_of_val(&bar_ptr), mem::size_of::<usize>());
1147
+ ///
1148
+ /// let footgun = &bar; // this is a shared reference to the zero-sized type identifying `bar`
1149
+ /// ```
1150
+ ///
1151
+ /// The last line shows that `&bar` is not a function pointer either. Rather, it
1152
+ /// is a reference to the function-specific ZST. `&bar` is basically never what you
1153
+ /// want when `bar` is a function.
1154
+ ///
1155
+ /// ### Traits
1117
1156
///
1118
1157
/// Function pointers implement the following traits:
1119
1158
///
0 commit comments