Skip to content

Commit 9a2426c

Browse files
committed
Rework the definitions of the extern ABIs
This updates the definitions of the extern ABIs to try to make them a little clearer as to what they mean. This also adds new statements about the equivalence of some ABIs to the "C" ABI.
1 parent 0275c80 commit 9a2426c

File tree

2 files changed

+46
-9
lines changed

2 files changed

+46
-9
lines changed

src/glossary.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@ The alignment of a value specifies what addresses values are preferred to
1111
start at. Always a power of two. References to a value must be aligned.
1212
[More][alignment].
1313

14+
### Application binary interface (ABI)
15+
16+
An *application binary interface* (ABI) defines the interface for compiled code to interact with other compiled code. With [`extern` blocks] and [`extern fn`], *ABI strings* affect:
17+
18+
- **Calling convention**: How function arguments are passed and values are returned (e.g., in registers or on the stack).
19+
- **Unwinding**: How stack unwinding is handled when a panic occurs. For example, the `"C-unwind"` ABI allows unwinding across the FFI boundary, while the `"C"` ABI does not.
20+
1421
### Arity
1522

1623
Arity refers to the number of arguments a function or operator takes.
@@ -287,6 +294,8 @@ uninhabited type is "empty" in the sense that there are no values of the type. T
287294
example of an uninhabited type is the [never type] `!`, or an enum with no variants
288295
`enum Never { }`. Opposite of [Inhabited](#inhabited).
289296

297+
[`extern` blocks]: items.extern
298+
[`extern fn`]: items.fn.extern
290299
[alignment]: type-layout.md#size-and-alignment
291300
[associated item]: #associated-item
292301
[attributes]: attributes.md

src/items/external-blocks.md

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -111,13 +111,16 @@ r[items.extern.abi.standard]
111111
The following ABI strings are supported on all platforms:
112112

113113
r[items.extern.abi.rust]
114-
* `unsafe extern "Rust"` --- The default ABI when you write a normal `fn foo()` in any Rust code.
114+
* `unsafe extern "Rust"` --- The native calling convention for Rust functions and closures. This is the default when the function's ABI is not specified. The Rust ABI offers no stability guarantees.
115115

116116
r[items.extern.abi.c]
117-
* `unsafe extern "C"` --- This is the same as `extern fn foo()`; whatever the default your C compiler supports.
117+
* `unsafe extern "C"` --- The "C" ABI attempts to match the default ABI chosen by the dominant C compiler for the target.
118118

119119
r[items.extern.abi.system]
120-
* `unsafe extern "system"` --- Usually the same as `extern "C"`, except on Win32, in which case it's `"stdcall"`, or what you should use to link to the Windows API itself.
120+
* `unsafe extern "system"` --- This is equivalent to `extern "C"` except on Windows x86_32 where it is equivalent to `"stdcall"`.
121+
122+
> [!NOTE]
123+
> As the correct underlying ABI on Windows is target-specific, it's best to use `extern "system"` when attempting to link Windows API functions that don't otherwise use a different ABI.
121124
122125
r[items.extern.abi.unwind]
123126
* `extern "C-unwind"` and `extern "system-unwind"` --- Identical to `"C"` and `"system"`, respectively, but with [different behavior][unwind-behavior] when the callee unwinds (by panicking or throwing a C++ style exception).
@@ -126,33 +129,57 @@ r[items.extern.abi.platform]
126129
There are also some platform-specific ABI strings:
127130

128131
r[items.extern.abi.cdecl]
129-
* `unsafe extern "cdecl"` --- The default for x86_32 C code.
132+
* `unsafe extern "cdecl"` --- The calling convention typically used with x86_32 C code.
130133
* Only available on x86_32 targets.
131134

135+
> [!NOTE]
136+
> See <https://learn.microsoft.com/en-us/cpp/cpp/cdecl> and <https://en.wikipedia.org/wiki/X86_calling_conventions#cdecl> for more information.
137+
132138
r[items.extern.abi.stdcall]
133-
* `unsafe extern "stdcall"` --- The default for the Win32 API on x86_32.
139+
* `unsafe extern "stdcall"` --- The calling convention typically used by the [Win32 API] on x86_32.
134140
* Only available on x86_32 targets.
135141

142+
> [!NOTE]
143+
> See <https://learn.microsoft.com/en-us/cpp/cpp/stdcall> and <https://en.wikipedia.org/wiki/X86_calling_conventions#stdcall> for more information.
144+
136145
r[items.extern.abi.win64]
137-
* `unsafe extern "win64"` --- The default for C code on x86_64 Windows.
146+
* `unsafe extern "win64"` --- The Windows x64 ABI.
138147
* Only available on x86_64 targets.
148+
* "win64" is the same as the "C" ABI on Windows x86_64 targets.
149+
150+
> [!NOTE]
151+
> See <https://learn.microsoft.com/en-us/cpp/build/x64-software-conventions> and <https://en.wikipedia.org/wiki/X86_calling_conventions#Microsoft_x64_calling_convention> for more information.
139152
140153
r[items.extern.abi.sysv64]
141-
* `unsafe extern "sysv64"` --- The default for C code on non-Windows x86_64.
154+
* `unsafe extern "sysv64"` --- The System V ABI.
142155
* Only available on x86_64 targets.
156+
* "sysv64" is the same as the "C" ABI on non-Windows x86_64 targets.
157+
158+
> [!NOTE]
159+
> See <https://wiki.osdev.org/System_V_ABI> or <https://en.wikipedia.org/wiki/X86_calling_conventions#System_V_AMD64_ABI> for more information.
143160
144161
r[items.extern.abi.aapcs]
145-
* `unsafe extern "aapcs"` --- The default for ARM.
162+
* `unsafe extern "aapcs"` --- The soft-float ABI for ARM.
146163
* Only available on ARM32 targets.
164+
* "aapcs" is the same as the "C" ABI on soft-float ARM32.
165+
166+
> [!NOTE]
167+
> See [Arm Procedure Call Standard](https://developer.arm.com/documentation/107656/0101/Getting-started-with-Armv8-M-based-systems/Procedure-Call-Standard-for-Arm-Architecture--AAPCS-) for more information.
147168
148169
r[items.extern.abi.fastcall]
149170
* `unsafe extern "fastcall"` --- The `fastcall` ABI --- corresponds to MSVC's `__fastcall` and GCC and clang's `__attribute__((fastcall))`.
150171
* Only available on x86_32 targets.
151172

173+
> [!NOTE]
174+
> See <https://learn.microsoft.com/en-us/cpp/cpp/fastcall> and <https://en.wikipedia.org/wiki/X86_calling_conventions#Microsoft_fastcall> for more information.
175+
152176
r[items.extern.abi.thiscall]
153-
* `unsafe extern "thiscall"` --- The default for C++ member functions on x86_32 MSVC --- corresponds to MSVC's `__thiscall` and GCC and clang's `__attribute__((thiscall))`.
177+
* `unsafe extern "thiscall"` --- The calling convention typically used on C++ class member functions on x86_32 MSVC --- corresponds to MSVC's `__thiscall` and GCC and clang's `__attribute__((thiscall))`.
154178
* Only available on x86_32 targets.
155179

180+
> [!NOTE]
181+
> See <https://en.wikipedia.org/wiki/X86_calling_conventions#thiscall> and <https://learn.microsoft.com/en-us/cpp/cpp/thiscall> for more information.
182+
156183
r[items.extern.abi.efiapi]
157184
* `unsafe extern "efiapi"` --- The ABI used for [UEFI] functions.
158185
* Only available on x86 and ARM targets (32bit and 64bit).
@@ -476,4 +503,5 @@ restrictions as [regular function parameters].
476503
[statics]: static-items.md
477504
[unwind-behavior]: functions.md#unwinding
478505
[value namespace]: ../names/namespaces.md
506+
[win32 api]: https://learn.microsoft.com/en-us/windows/win32/api/
479507
[`link_ordinal`]: items.extern.attributes.link_ordinal

0 commit comments

Comments
 (0)