]>
Commit | Line | Data |
---|---|---|
1 | # `ffi_const` | |
2 | ||
3 | The tracking issue for this feature is: [#58328] | |
4 | ||
5 | ------ | |
6 | ||
7 | The `#[ffi_const]` attribute applies clang's `const` attribute to foreign | |
8 | functions declarations. | |
9 | ||
10 | That is, `#[ffi_const]` functions shall have no effects except for its return | |
11 | value, which can only depend on the values of the function parameters, and is | |
12 | not affected by changes to the observable state of the program. | |
13 | ||
14 | Applying the `#[ffi_const]` attribute to a function that violates these | |
15 | requirements is undefined behaviour. | |
16 | ||
17 | This attribute enables Rust to perform common optimizations, like sub-expression | |
18 | elimination, and it can avoid emitting some calls in repeated invocations of the | |
19 | function with the same argument values regardless of other operations being | |
20 | performed in between these functions calls (as opposed to `#[ffi_pure]` | |
21 | functions). | |
22 | ||
23 | ## Pitfalls | |
24 | ||
25 | A `#[ffi_const]` function can only read global memory that would not affect | |
26 | its return value for the whole execution of the program (e.g. immutable global | |
27 | memory). `#[ffi_const]` functions are referentially-transparent and therefore | |
28 | more strict than `#[ffi_pure]` functions. | |
29 | ||
30 | A common pitfall involves applying the `#[ffi_const]` attribute to a | |
31 | function that reads memory through pointer arguments which do not necessarily | |
32 | point to immutable global memory. | |
33 | ||
34 | A `#[ffi_const]` function that returns unit has no effect on the abstract | |
35 | machine's state, and a `#[ffi_const]` function cannot be `#[ffi_pure]`. | |
36 | ||
37 | A `#[ffi_const]` function must not diverge, neither via a side effect (e.g. a | |
38 | call to `abort`) nor by infinite loops. | |
39 | ||
40 | When translating C headers to Rust FFI, it is worth verifying for which targets | |
41 | the `const` attribute is enabled in those headers, and using the appropriate | |
42 | `cfg` macros in the Rust side to match those definitions. While the semantics of | |
43 | `const` are implemented identically by many C and C++ compilers, e.g., clang, | |
44 | [GCC], [ARM C/C++ compiler], [IBM ILE C/C++], etc. they are not necessarily | |
45 | implemented in this way on all of them. It is therefore also worth verifying | |
46 | that the semantics of the C toolchain used to compile the binary being linked | |
47 | against are compatible with those of the `#[ffi_const]`. | |
48 | ||
49 | [#58328]: https://github.com/rust-lang/rust/issues/58328 | |
50 | [ARM C/C++ compiler]: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0491c/Cacgigch.html | |
51 | [GCC]: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-const-function-attribute | |
52 | [IBM ILE C/C++]: https://www.ibm.com/support/knowledgecenter/fr/ssw_ibm_i_71/rzarg/fn_attrib_const.htm |