Skip to content

Commit 615815f

Browse files
Add documentation for [[msvc::musttail]] attribute (#5862)
* Add documentation for [[msvc::musttail]] attribute --------- Co-authored-by: Tyler Whitney <[email protected]>
1 parent b8ef7b5 commit 615815f

File tree

1 file changed

+53
-3
lines changed

1 file changed

+53
-3
lines changed

docs/cpp/attributes.md

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
---
22
title: "Attributes in C++"
33
description: "Learn more about: Attributes in C++"
4-
f1_keywords: ["deprecated", "noreturn", "carries_dependency", "fallthrough", "nodiscard", "maybe_unused", "likely", "unlikely", "gsl::suppress", "msvc::flatten", "msvc::forceinline", "msvc::forceinline_calls", "msvc::intrinsic", "msvc::noinline", "msvc::noinline_calls", "msvc::no_tls_guard"]
5-
helpviewer_keywords: ["deprecated", "noreturn", "carries_dependency", "fallthrough", "nodiscard", "maybe_unused", "likely", "unlikely", "gsl::suppress", "msvc::flatten", "msvc::forceinline", "msvc::forceinline_calls", "msvc::intrinsic", "msvc::noinline", "msvc::noinline_calls", "msvc::no_tls_guard"]
6-
ms.date: 4/13/2023
4+
f1_keywords: ["deprecated", "noreturn", "carries_dependency", "fallthrough", "nodiscard", "maybe_unused", "likely", "unlikely", "gsl::suppress", "msvc::flatten", "msvc::forceinline", "msvc::forceinline_calls", "msvc::intrinsic", "msvc::noinline", "msvc::noinline_calls", "msvc::no_tls_guard", "msvc::musttail"]
5+
helpviewer_keywords: ["deprecated", "noreturn", "carries_dependency", "fallthrough", "nodiscard", "maybe_unused", "likely", "unlikely", "gsl::suppress", "msvc::flatten", "msvc::forceinline", "msvc::forceinline_calls", "msvc::intrinsic", "msvc::noinline", "msvc::noinline_calls", "msvc::no_tls_guard", "msvc::musttail"]
6+
ms.date: 12/9/2025
77
---
88

99
# Attributes in C++
@@ -159,6 +159,56 @@ void f() {
159159
}
160160
```
161161

162+
### `[[msvc::musttail]]`
163+
164+
The `[[msvc::musttail]]` attribute, introduced in [MSVC Build Tools version 14.50](../overview/what-s-new-for-msvc.md#whats-new-for-msvc-build-tools-version-1450), is an experimental x64-only Microsoft-specific attribute that enforces tail-call optimization. When applied to a qualifying return statement, it instructs the compiler to emit the call as a tail call. If the compiler can't emit the tail call, it produces a compilation error. The `[[msvc::musttail]]` attribute enforces a tail call instead of inlining the function.
165+
166+
`[[msvc::musttail]]` requirements:
167+
- The caller and callee must have matching return types.
168+
- The calling conventions must be compatible.
169+
- The tail call must be the final action in the calling function.
170+
- The callee can't use more stack space than the calling function.
171+
- If more than four integer parameters are passed, the calling function must allocate enough stack space for those additional arguments.
172+
- Compile with `/O2` or `/O2 /GL` optimization level.
173+
174+
#### Example
175+
176+
Tail calls are a compiler optimization that is possible when a function call is the last action performed before returning. Instead of creating a new stack frame to call the function, the current function's stack frame is reused. This reduces stack usage and improves performance—especially in recursive scenarios.
177+
178+
In the following code, the `[[msvc::musttail]]` attribute applied to `return increment(x)` causes control to transfer directly to `increment`. When `increment` reaches the `return x+1;` statement, its result is provided directly to the caller of `incrementIfPositive`, that is `main`. This replaces inlining `increment` into `incrementIfPositive` or calling `increment` from `incrementIfPositive` and returning to `incrementIfPositive` before returning to `main`. The tail call optimization eliminates the need for `incrementIfPositive` to regain control after `increment` finishes. This is a performance optimization that reduces stack usage, especially useful in recursive scenarios.
179+
180+
```cpp
181+
// compile with /O2
182+
#include <iostream>
183+
184+
int increment(int x)
185+
{
186+
return x + 1;
187+
}
188+
189+
int incrementIfPositive(int x)
190+
{
191+
if (x > 0)
192+
{
193+
[[msvc::musttail]]
194+
return increment(x);
195+
}
196+
return -1;
197+
}
198+
199+
int main()
200+
{
201+
int result = incrementIfPositive(42);
202+
if (result < 0)
203+
{
204+
return -1;
205+
}
206+
207+
std::cout << result; // outputs 43
208+
return 0;
209+
}
210+
```
211+
162212
### `[[msvc::noinline]]`
163213
164214
When placed before a function declaration, the Microsoft-specific attribute `[[msvc::noinline]]` has the same meaning as `__declspec(noinline)`.

0 commit comments

Comments
 (0)