@@ -107,35 +107,73 @@ component after the function name. This might be necessary if there is not
107
107
sufficient context to determine the type parameters. For example,
108
108
` mem::size_of::<u32>() == 4 ` .
109
109
110
- ## Extern functions
110
+ ## Extern function qualifier
111
111
112
- Extern functions are part of Rust's foreign function interface, providing the
113
- opposite functionality to [ external blocks] . Whereas external
114
- blocks allow Rust code to call foreign code, extern functions with bodies
115
- defined in Rust code _ can be called by foreign code_ . They are defined in the
116
- same way as any other Rust function, except that they have the ` extern `
117
- qualifier.
112
+ The ` extern ` function qualifier allows providing function _ definitions_ that can
113
+ be called with a particular ABI:
114
+
115
+ ``` rust,ignore
116
+ extern "ABI" fn foo() { ... }
117
+ ```
118
+
119
+ These are often used in combination with [ external block] items which provide
120
+ function _ declarations_ that can be used to call functions without providing
121
+ their _ definition_ :
122
+
123
+ ``` rust,ignore
124
+ extern "ABI" {
125
+ fn foo(); /* no body */
126
+ }
127
+ unsafe { foo() }
128
+ ```
129
+
130
+ When ` "extern" Abi?* ` is omitted from ` FunctionQualifiers ` in function items,
131
+ the ABI ` "Rust" ` is assigned. For example:
118
132
119
133
``` rust
120
- // Declares an extern fn, the ABI defaults to "C"
121
- extern fn new_i32 () -> i32 { 0 }
134
+ fn foo () {}
135
+ ```
136
+
137
+ is equivalent to:
122
138
123
- // Declares an extern fn with "stdcall" ABI
139
+ ``` rust
140
+ extern " Rust" fn foo () {}
141
+ ```
142
+
143
+ Functions in Rust can be called by foreign code, and using an ABI that
144
+ differs from Rust allows, for example, to provide functions that can be
145
+ called from other programming languages like C:
146
+
147
+ ``` rust
148
+ // Declares a function with the "C" ABI
149
+ extern " C" fn new_i32 () -> i32 { 0 }
150
+
151
+ // Declares a function with the "stdcall" ABI
124
152
# #[cfg(target_arch = " x86_64" )]
125
153
extern " stdcall" fn new_i32_stdcall () -> i32 { 0 }
126
154
```
127
155
128
- Unlike normal functions, extern fns have type ` extern "ABI" fn() ` . This is the
129
- same type as the functions declared in an extern block.
156
+ Just as with [ external block ] , when the ` extern ` keyword is used and the ` "ABI `
157
+ is omitted, the ABI used defaults to ` "C" ` . That is, this:
130
158
131
159
``` rust
132
- # extern fn new_i32 () -> i32 { 0 }
160
+ extern fn new_i32 () -> i32 { 0 }
161
+ let fptr : extern fn () -> i32 = new_i32 ;
162
+ ```
163
+
164
+ is equivalent to:
165
+
166
+ ``` rust
167
+ extern " C" fn new_i32 () -> i32 { 0 }
133
168
let fptr : extern " C" fn () -> i32 = new_i32 ;
134
169
```
135
170
136
- As non-Rust calling conventions do not support unwinding, unwinding past the end
137
- of an extern function will cause the process to abort. In LLVM, this is
138
- implemented by executing an illegal instruction.
171
+ Functions with an ABI that differs from ` "Rust" ` do not support unwinding in the
172
+ exact same way that Rust does. Therefore, unwinding past the end of functions
173
+ with such ABIs causes the process to abort.
174
+
175
+ > ** Note** : The LLVM backend of the ` rustc ` implementation
176
+ aborts the process by executing an illegal instruction.
139
177
140
178
## Const functions
141
179
@@ -243,3 +281,4 @@ attributes macros.
243
281
[ `export_name` ] : ../abi.md#the-export_name-attribute
244
282
[ `link_section` ] : ../abi.md#the-link_section-attribute
245
283
[ `no_mangle` ] : ../abi.md#the-no_mangle-attribute
284
+ [ external_block_abi ] : external-blocks.md#abi
0 commit comments