Movatterモバイル変換


[0]ホーム

URL:


fn

Primitive Typefn 

1.0.0
Expand description

Function pointers, likefn(usize) -> bool.

See also the traitsFn,FnMut, andFnOnce.

Function pointers are pointers that point tocode, not data. They can be calledjust like functions. Like references, function pointers are, among other things, assumed tonot be null, so if you want to pass a function pointer over FFI and be able to accommodate nullpointers, make your typeOption<fn()>with your required signature.

Note that FFI requires additional care to ensure that the ABI for both sides of the call match.The exact requirements are not currently documented.

§Safety

Plain function pointers are obtained by casting either plain functions, or closures that don’tcapture an environment:

fnadd_one(x: usize) -> usize {    x +1}letptr:fn(usize) -> usize = add_one;assert_eq!(ptr(5),6);letclos:fn(usize) -> usize = |x| x +5;assert_eq!(clos(5),10);

In addition to varying based on their signature, function pointers come in two flavors: safeand unsafe. Plainfn() function pointers can only point to safe functions,whileunsafe fn() function pointers can point to safe or unsafe functions.

fnadd_one(x: usize) -> usize {    x +1}unsafe fnadd_one_unsafely(x: usize) -> usize {    x +1}letsafe_ptr:fn(usize) -> usize = add_one;//ERROR: mismatched types: expected normal fn, found unsafe fn//let bad_ptr: fn(usize) -> usize = add_one_unsafely;letunsafe_ptr:unsafe fn(usize) -> usize = add_one_unsafely;letreally_safe_ptr:unsafe fn(usize) -> usize = add_one;

§ABI

On top of that, function pointers can vary based on what ABI they use. Thisis achieved by adding theextern keyword before the type, followed by theABI in question. The default ABI is “Rust”, i.e.,fn() is the exact sametype asextern "Rust" fn(). A pointer to a function with C ABI would havetypeextern "C" fn().

extern "ABI" { ... } blocks declare functions with ABI “ABI”. The defaulthere is “C”, i.e., functions declared in anextern {...} block have “C”ABI.

For more information and a list of supported ABIs, seethe nomicon’ssection on foreign calling conventions.

§Variadic functions

Extern function declarations with the “C” or “cdecl” ABIs can also bevariadic, allowing themto be called with a variable number of arguments. Normal Rust functions, even those with anextern "ABI", cannot be variadic. For more information, seethe nomicon’s section onvariadic functions.

§Creating function pointers

Whenbar is the name of a function, then the expressionbar isnot afunction pointer. Rather, it denotes a value of an unnameable type thatuniquely identifies the functionbar. The value is zero-sized because thetype already identifies the function. This has the advantage that “calling”the value (it implements theFn* traits) does not require dynamicdispatch.

This zero-sized typecoerces to a regular function pointer. For example:

fnbar(x: i32) {}letnot_bar_ptr = bar;// `not_bar_ptr` is zero-sized, uniquely identifying `bar`assert_eq!(size_of_val(&not_bar_ptr),0);letbar_ptr:fn(i32) = not_bar_ptr;// force coercion to function pointerassert_eq!(size_of_val(&bar_ptr), size_of::<usize>());letfootgun =&bar;// this is a shared reference to the zero-sized type identifying `bar`

The last line shows that&bar is not a function pointer either. Rather, itis a reference to the function-specific ZST.&bar is basically never what youwant whenbar is a function.

§Casting to and from integers

You can cast function pointers directly to integers:

letfnptr:fn(i32) -> i32 = |x| x+2;letfnptr_addr = fnptrasusize;

However, a direct cast back is not possible. You need to usetransmute:

letfnptr = fnptr_addras*const();letfnptr:fn(i32) -> i32 =unsafe{ std::mem::transmute(fnptr) };assert_eq!(fnptr(40),42);

Crucially, weas-cast to a raw pointer beforetransmuteing to a function pointer.This avoids an integer-to-pointertransmute, 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 pointershave different sizes.

§ABI compatibility

Generally, when a function is declared with one signature and called via a function pointer witha different signature, the two signatures must beABI-compatible or else calling the functionvia that function pointer is Undefined Behavior. ABI compatibility is a lot stricter than merelyhaving the same memory layout; for example, even ifi32 andf32 have the same size andalignment, they might be passed in different registers and hence not be ABI-compatible.

ABI compatibility as a concern only arises in code that alters the type of function pointers,and code that imports functions viaextern blocks. Altering the type of function pointers iswildly unsafe (as in, a lot more unsafe than eventransmute_copy), andshould only occur in the most exceptional circumstances. Most Rust code just imports functionsviause. So, most likely you do not have to worry about ABI compatibility.

But assuming such circumstances, what are the rules? For this section, we are only consideringthe ABI of direct Rust-to-Rust calls (with both definition and callsite visible to theRust compiler), not linking in general – once functions are imported viaextern blocks, thereare more things to consider that we do not go into here. Note that this also applies topassing/calling functions across language boundaries via function pointers.

Nothing in this section should be taken as a guarantee for non-Rust-to-Rust calls, even withtypes fromcore::ffi orlibc.

For two signatures to be consideredABI-compatible, they must use a compatible ABI string,must take the same number of arguments, and the individual argument types and the return typesmust be ABI-compatible. The ABI string is declared viaextern "ABI" fn(...) -> ...; note thatfn name(...) -> ... implicitly uses the"Rust" ABI string andextern fn name(...) -> ...implicitly uses the"C" ABI string.

The ABI strings are guaranteed to be compatible if they are the same, or if the caller ABIstring is$X-unwind and the callee ABI string is$X, where$X is one of the following:“C”, “aapcs”, “fastcall”, “stdcall”, “system”, “sysv64”, “thiscall”, “vectorcall”, “win64”.

The following types are guaranteed to be ABI-compatible:

  • *const T,*mut T,&T,&mut T,Box<T> (specifically, onlyBox<T, Global>), andNonNull<T> are all ABI-compatible with each other for allT. They are also ABI-compatiblewith each other fordifferentT if they have the same metadata type (<T as Pointee>::Metadata).
  • usize is ABI-compatible with theuN integer type of the same size, and likewiseisize isABI-compatible with theiN integer type of the same size.
  • char is ABI-compatible withu32.
  • Any twofn (function pointer) types are ABI-compatible with each other if they have the sameABI string or the ABI string only differs in a trailing-unwind, independent of the rest oftheir signature. (This means you can passfn() to a function expectingfn(i32), and thecall will be valid ABI-wise. The callee receives the result of transmuting the function pointerfromfn() tofn(i32); that transmutation is itself a well-defined operation, it’s justalmost certainly UB to later call that function pointer.)
  • Any two types with size 0 and alignment 1 are ABI-compatible.
  • Arepr(transparent) typeT is ABI-compatible with its unique non-trivial field, i.e., theunique field that doesn’t have size 0 and alignment 1 (if there is such a field).
  • i32 is ABI-compatible withNonZero<i32>, and similar for all other integer types.
  • IfT is guaranteed to be subject to thenull pointeroptimization, andE is an enum satisfying the followingrequirements, thenT andE are ABI-compatible. Such an enumE is called “option-like”.
    • The enumE uses theRust representation, and is not modified by thealign orpacked representation modifiers.
    • The enumE has exactly two variants.
    • One variant has exactly one field, of typeT.
    • All fields of the other variant are zero-sized with 1-byte alignment.

Furthermore, ABI compatibility satisfies the following general properties:

  • Every type is ABI-compatible with itself.
  • IfT1 andT2 are ABI-compatible andT2 andT3 are ABI-compatible, then so areT1 andT3 (i.e., ABI-compatibility is transitive).
  • IfT1 andT2 are ABI-compatible, then so areT2 andT1 (i.e., ABI-compatibility issymmetric).

More signatures can be ABI-compatible on specific targets, but that should not be relied uponsince it is not portable and not a stable guarantee.

Noteworthy cases of typesnot being ABI-compatible in general are:

  • bool vsu8,i32 vsu32,char vsi32: on some targets, the calling conventions forthese types differ in terms of what they guarantee for the remaining bits in the register thatare not used by the value.
  • i32 vsf32 are not compatible either, as has already been mentioned above.
  • struct Foo(u32) andu32 are not compatible (withoutrepr(transparent)) since structs areaggregate types and often passed in a different way than primitives likei32.

Note that these rules describe when two completely known types are ABI-compatible. Whenconsidering ABI compatibility of a type declared in another crate (including the standardlibrary), consider that any type that has a private field or the#[non_exhaustive] attributemay change its layout as a non-breaking update unless documented otherwise – so for instance,even if such a type is a 1-ZST orrepr(transparent) right now, this might change with anylibrary version bump.

If the declared signature and the signature of the function pointer are ABI-compatible, then thefunction call behaves as if every argument wastransmuted from thetype in the function pointer to the type at the function declaration, and the return value istransmuted from the type in the declaration to the type in thepointer. All the usual caveats and concerns around transmutation apply; for instance, if thefunction expects aNonZero<i32> and the function pointer uses the ABI-compatible typeOption<NonZero<i32>>, and the value used for the argument isNone, then this call is UndefinedBehavior since transmutingNone::<NonZero<i32>> toNonZero<i32> violates the non-zerorequirement.

§Trait implementations

In this documentation the shorthandfn(T₁, T₂, …, Tₙ) is used to represent non-variadicfunction pointers of varying length. Note that this is a convenience notation to avoidrepetitive documentation, not valid Rust syntax.

The following traits are implemented for function pointers with any number of arguments andany ABI.

Note that while this type implementsPartialEq, comparing function pointers is unreliable:pointers to the same function can compare inequal (because functions are duplicated in multiplecodegen units), and pointers todifferent functions can compare equal (since identicalfunctions can be deduplicated within a codegen unit).

In addition, allsafe function pointers implementFn,FnMut, andFnOnce, becausethese traits are specially known to the compiler.

Auto Trait Implementations§

§

impl<Ret, T>Freeze forfn(T₁, T₂, …, Tₙ) -> Ret

§

impl<Ret, T>RefUnwindSafe forfn(T₁, T₂, …, Tₙ) -> Ret

§

impl<Ret, T>Send forfn(T₁, T₂, …, Tₙ) -> Ret

§

impl<Ret, T>Sync forfn(T₁, T₂, …, Tₙ) -> Ret

§

impl<Ret, T>Unpin forfn(T₁, T₂, …, Tₙ) -> Ret

§

impl<Ret, T>UnwindSafe forfn(T₁, T₂, …, Tₙ) -> Ret

Blanket Implementations§

Source§

impl<T>Any for T
where T: 'static + ?Sized,

Source§

fntype_id(&self) ->TypeId

Gets theTypeId ofself.Read more
Source§

impl<T>Borrow<T> for T
where T: ?Sized,

Source§

fnborrow(&self) ->&T

Immutably borrows from an owned value.Read more
Source§

impl<T>BorrowMut<T> for T
where T: ?Sized,

Source§

fnborrow_mut(&mut self) ->&mut T

Mutably borrows from an owned value.Read more
Source§

impl<T>CloneToUninit for T
where T:Clone,

Source§

unsafe fnclone_to_uninit(&self, dest:*mutu8)

🔬This is a nightly-only experimental API. (clone_to_uninit #126799)
Performs copy-assignment fromself todest.Read more
Source§

impl<F>Debug for F
where F:FnPtr,

Source§

fnfmt(&self, f: &mutFormatter<'_>) ->Result<(),Error>

Formats the value using the given formatter.Read more
Source§

impl<T>From<T> for T

Source§

fnfrom(t: T) -> T

Returns the argument unchanged.

Source§

impl<F>Hash for F
where F:FnPtr,

Source§

fnhash<HH>(&self, state:&mut HH)
where HH:Hasher,

Feeds this value into the givenHasher.Read more
1.3.0 ·Source§

fnhash_slice<H>(data: &[Self], state:&mut H)
where H:Hasher, Self:Sized,

Feeds a slice of this type into the givenHasher.Read more
Source§

impl<T, U>Into<U> for T
where U:From<T>,

Source§

fninto(self) -> U

CallsU::from(self).

That is, this conversion is whatever the implementation ofFrom<T> for U chooses to do.

Source§

impl<F>Ord for F
where F:FnPtr,

Source§

fncmp(&self, other:&F) ->Ordering

This method returns anOrdering betweenself andother.Read more
1.21.0 ·Source§

fnmax(self, other: Self) -> Self
where Self:Sized,

Compares and returns the maximum of two values.Read more
1.21.0 ·Source§

fnmin(self, other: Self) -> Self
where Self:Sized,

Compares and returns the minimum of two values.Read more
1.50.0 ·Source§

fnclamp(self, min: Self, max: Self) -> Self
where Self:Sized,

Restrict a value to a certain interval.Read more
Source§

impl<F>PartialEq for F
where F:FnPtr,

Source§

fneq(&self, other:&F) ->bool

Tests forself andother values to be equal, and is used by==.
1.0.0 ·Source§

fnne(&self, other:&Rhs) ->bool

Tests for!=. The default implementation is almost always sufficient,and should not be overridden without very good reason.
Source§

impl<F>PartialOrd for F
where F:FnPtr,

Source§

fnpartial_cmp(&self, other:&F) ->Option<Ordering>

This method returns an ordering betweenself andother values if one exists.Read more
1.0.0 ·Source§

fnlt(&self, other:&Rhs) ->bool

Tests less than (forself andother) and is used by the< operator.Read more
1.0.0 ·Source§

fnle(&self, other:&Rhs) ->bool

Tests less than or equal to (forself andother) and is used by the<= operator.Read more
1.0.0 ·Source§

fngt(&self, other:&Rhs) ->bool

Tests greater than (forself andother) and is used by the>operator.Read more
1.0.0 ·Source§

fnge(&self, other:&Rhs) ->bool

Tests greater than or equal to (forself andother) and is used bythe>= operator.Read more
Source§

impl<F>Pattern for F
where F:FnMut(char) ->bool,

Source§

typeSearcher<'a> =CharPredicateSearcher<'a, F>

🔬This is a nightly-only experimental API. (pattern #27721)
Associated searcher for this pattern
Source§

fninto_searcher<'a>(self, haystack: &'astr) ->CharPredicateSearcher<'a, F>

🔬This is a nightly-only experimental API. (pattern #27721)
Constructs the associated searcher fromself and thehaystack to search in.
Source§

fnis_contained_in<'a>(self, haystack: &'astr) ->bool

🔬This is a nightly-only experimental API. (pattern #27721)
Checks whether the pattern matches anywhere in the haystack
Source§

fnis_prefix_of<'a>(self, haystack: &'astr) ->bool

🔬This is a nightly-only experimental API. (pattern #27721)
Checks whether the pattern matches at the front of the haystack
Source§

fnstrip_prefix_of<'a>(self, haystack: &'astr) ->Option<&'astr>

🔬This is a nightly-only experimental API. (pattern #27721)
Removes the pattern from the front of haystack, if it matches.
Source§

fnis_suffix_of<'a>(self, haystack: &'astr) ->bool

🔬This is a nightly-only experimental API. (pattern #27721)
Checks whether the pattern matches at the back of the haystack
Source§

fnstrip_suffix_of<'a>(self, haystack: &'astr) ->Option<&'astr>

🔬This is a nightly-only experimental API. (pattern #27721)
Removes the pattern from the back of haystack, if it matches.
Source§

fnas_utf8_pattern(&self) ->Option<Utf8Pattern<'_>>

🔬This is a nightly-only experimental API. (pattern #27721)
Returns the pattern as utf-8 bytes if possible.
Source§

impl<F>Pointer for F
where F:FnPtr,

Source§

fnfmt(&self, f: &mutFormatter<'_>) ->Result<(),Error>

Formats the value using the given formatter.Read more
Source§

impl<T>ToOwned for T
where T:Clone,

Source§

typeOwned = T

The resulting type after obtaining ownership.
Source§

fnto_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning.Read more
Source§

fnclone_into(&self, target:&mut T)

Uses borrowed data to replace owned data, usually by cloning.Read more
Source§

impl<T, U>TryFrom<U> for T
where U:Into<T>,

Source§

typeError =Infallible

The type returned in the event of a conversion error.
Source§

fntry_from(value: U) ->Result<T, <T asTryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U>TryInto<U> for T
where U:TryFrom<T>,

Source§

typeError = <U asTryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fntry_into(self) ->Result<U, <U asTryFrom<T>>::Error>

Performs the conversion.
Source§

impl<F>Eq for F
where F:FnPtr,


[8]ページ先頭

©2009-2026 Movatter.jp