diff options
| author | Matthias Schiffer <mschiffer@universe-factory.net> | 2020-04-14 00:21:27 +0200 |
|---|---|---|
| committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2020-05-20 01:16:11 +0200 |
| commit | a114a237231586e754f8d6de2759e69ee9d90a2c (patch) | |
| tree | 4605361afbf6c1c9098fefc11ae33e2fa3327acb | |
| parent | a7d7f0bbe962811d2e5207762aa92c2059c33d1a (diff) | |
| download | rust-a114a237231586e754f8d6de2759e69ee9d90a2c.tar.gz rust-a114a237231586e754f8d6de2759e69ee9d90a2c.zip | |
Document `#[ffi_const]` and `#[ffi_pure]` function attributes in unstable book
Based on the work of gnzlbg <gonzalobg88@gmail.com>.
| -rw-r--r-- | src/doc/unstable-book/src/language-features/ffi-const.md | 47 | ||||
| -rw-r--r-- | src/doc/unstable-book/src/language-features/ffi-pure.md | 51 |
2 files changed, 98 insertions, 0 deletions
diff --git a/src/doc/unstable-book/src/language-features/ffi-const.md b/src/doc/unstable-book/src/language-features/ffi-const.md new file mode 100644 index 00000000000..9a1ced4033b --- /dev/null +++ b/src/doc/unstable-book/src/language-features/ffi-const.md @@ -0,0 +1,47 @@ +# `ffi_const` + +The `#[ffi_const]` attribute applies clang's `const` attribute to foreign +functions declarations. + +That is, `#[ffi_const]` functions shall have no effects except for its return +value, which can only depend on the values of the function parameters, and is +not affected by changes to the observable state of the program. + +Applying the `#[ffi_const]` attribute to a function that violates these +requirements is undefined behaviour. + +This attribute enables Rust to perform common optimizations, like sub-expression +elimination, and it can avoid emitting some calls in repeated invocations of the +function with the same argument values regardless of other operations being +performed in between these functions calls (as opposed to `#[ffi_pure]` +functions). + +## Pitfalls + +A `#[ffi_const]` function can only read global memory that would not affect +its return value for the whole execution of the program (e.g. immutable global +memory). `#[ffi_const]` functions are referentially-transparent and therefore +more strict than `#[ffi_pure]` functions. + +A common pitfall involves applying the `#[ffi_const]` attribute to a +function that reads memory through pointer arguments which do not necessarily +point to immutable global memory. + +A `#[ffi_const]` function that returns unit has no effect on the abstract +machine's state, and a `#[ffi_const]` function cannot be `#[ffi_pure]`. + +A `#[ffi_const]` function must not diverge, neither via a side effect (e.g. a +call to `abort`) nor by infinite loops. + +When translating C headers to Rust FFI, it is worth verifying for which targets +the `const` attribute is enabled in those headers, and using the appropriate +`cfg` macros in the Rust side to match those definitions. While the semantics of +`const` are implemented identically by many C and C++ compilers, e.g., clang, +[GCC], [ARM C/C++ compiler], [IBM ILE C/C++], etc. they are not necessarily +implemented in this way on all of them. It is therefore also worth verifying +that the semantics of the C toolchain used to compile the binary being linked +against are compatible with those of the `#[ffi_const]`. + +[ARM C/C++ compiler]: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0491c/Cacgigch.html +[GCC]: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-const-function-attribute +[IBM ILE C/C++]: https://www.ibm.com/support/knowledgecenter/fr/ssw_ibm_i_71/rzarg/fn_attrib_const.htm diff --git a/src/doc/unstable-book/src/language-features/ffi-pure.md b/src/doc/unstable-book/src/language-features/ffi-pure.md new file mode 100644 index 00000000000..7bfd7a378f0 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/ffi-pure.md @@ -0,0 +1,51 @@ +# `ffi_pure` + +The `#[ffi_pure]` attribute applies clang's `pure` attribute to foreign +functions declarations. + +That is, `#[ffi_pure]` functions shall have no effects except for its return +value, which shall not change across two consecutive function calls with +the same parameters. + +Applying the `#[ffi_pure]` attribute to a function that violates these +requirements is undefined behavior. + +This attribute enables Rust to perform common optimizations, like sub-expression +elimination and loop optimizations. Some common examples of pure functions are +`strlen` or `memcmp`. + +These optimizations are only applicable when the compiler can prove that no +program state observable by the `#[ffi_pure]` function has changed between calls +of the function, which could alter the result. See also the `#[ffi_const]` +attribute, which provides stronger guarantees regarding the allowable behavior +of a function, enabling further optimization. + +## Pitfalls + +A `#[ffi_pure]` function can read global memory through the function +parameters (e.g. pointers), globals, etc. `#[ffi_pure]` functions are not +referentially-transparent, and are therefore more relaxed than `#[ffi_const]` +functions. + +However, accesing global memory through volatile or atomic reads can violate the +requirement that two consecutive function calls shall return the same value. + +A `pure` function that returns unit has no effect on the abstract machine's +state. + +A `#[ffi_pure]` function must not diverge, neither via a side effect (e.g. a +call to `abort`) nor by infinite loops. + +When translating C headers to Rust FFI, it is worth verifying for which targets +the `pure` attribute is enabled in those headers, and using the appropriate +`cfg` macros in the Rust side to match those definitions. While the semantics of +`pure` are implemented identically by many C and C++ compilers, e.g., clang, +[GCC], [ARM C/C++ compiler], [IBM ILE C/C++], etc. they are not necessarily +implemented in this way on all of them. It is therefore also worth verifying +that the semantics of the C toolchain used to compile the binary being linked +against are compatible with those of the `#[ffi_pure]`. + + +[ARM C/C++ compiler]: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0491c/Cacigdac.html +[GCC]: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-pure-function-attribute +[IBM ILE C/C++]: https://www.ibm.com/support/knowledgecenter/fr/ssw_ibm_i_71/rzarg/fn_attrib_pure.htm |
