|
1 | 1 | --- |
2 | 2 | title: "Attributes in C++" |
3 | 3 | 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 |
7 | 7 | --- |
8 | 8 |
|
9 | 9 | # Attributes in C++ |
@@ -159,6 +159,56 @@ void f() { |
159 | 159 | } |
160 | 160 | ``` |
161 | 161 |
|
| 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 | +
|
162 | 212 | ### `[[msvc::noinline]]` |
163 | 213 |
|
164 | 214 | When placed before a function declaration, the Microsoft-specific attribute `[[msvc::noinline]]` has the same meaning as `__declspec(noinline)`. |
|
0 commit comments