diff --git a/.acrolinx-config.edn b/.acrolinx-config.edn
deleted file mode 100644
index 78cdd0e4df0..00000000000
--- a/.acrolinx-config.edn
+++ /dev/null
@@ -1,27 +0,0 @@
-{:allowed-branchname-matches ["main" "release-.*"]
- :allowed-filename-matches ["docs" "styleguide"]
-
- :template-header
- "
-## Acrolinx Scorecards
-
- Click the scorecard links for each article to review the Acrolinx feedback on grammar, spelling, punctuation, writing style, and terminology:
-
-| Article | Score | Issues | Scorecard |
-| ------- | ----- | ------ | --------- |
-"
-
- ;; do not remove the spaces at the end of lines! That is markdown for
- ;; linebreak
- :template-change
- "| **${github/filename}** | ${acrolinx/qualityscore} | ${acrolinx/flags/issues} | [link](${acrolinx/scorecard}) |
-"
-
- :template-footer
-"
-**More info about Acrolinx**
-
-- [Install Acrolinx locally for VS Code](https://review.docs.microsoft.com/en-us/help/contribute/contribute-acrolinx-vscode)
-- [Report false positives or issues](https://aka.ms/acrolinxbug)
-
-"}
diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md
index 75e32e18c89..6498b2c6631 100644
--- a/.github/copilot-instructions.md
+++ b/.github/copilot-instructions.md
@@ -15,6 +15,9 @@ This document uses the following markers to indicate instruction priority:
## General Guidelines
+### Using MCP tools
+If the user intent relates to Azure Devops, make sure to prioritize the Azure DevOps MCP server tools.
+
### 1. Issue Handling
When creating a PR for an issue:
- [ ] Read the full issue and all linked references
diff --git a/.github/workflows/generate-preview-links.yml b/.github/workflows/generate-preview-links.yml
new file mode 100644
index 00000000000..784d2be5b6e
--- /dev/null
+++ b/.github/workflows/generate-preview-links.yml
@@ -0,0 +1,25 @@
+name: 'Preview link generator'
+
+on:
+ pull_request_target:
+ types: [opened, synchronize, reopened]
+
+permissions:
+ contents: read
+
+jobs:
+ preview_link_generator_job:
+ name: Generate preview link table
+ runs-on: ubuntu-latest
+ permissions:
+ statuses: read
+ pull-requests: write
+ steps:
+ - name: Harden Runner
+ uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1
+ with:
+ egress-policy: audit
+
+ - uses: dotnet/docs-tools/actions/preview-link-generator@main
+ with:
+ repo_token: ${{ secrets.GITHUB_TOKEN }}
\ No newline at end of file
diff --git a/.openpublishing.redirection.json b/.openpublishing.redirection.json
index 717a62c31c1..e437970bff5 100644
--- a/.openpublishing.redirection.json
+++ b/.openpublishing.redirection.json
@@ -1,5 +1,10 @@
{
"redirections": [
+ {
+ "source_path": "docs/porting/copilot-app-modernization-cpp.md",
+ "redirect_url": "/cpp/porting/github-copilot-modernization-cpp/overview",
+ "redirect_document_id": true
+ },
{
"source_path": "docs/parallel/amp/cpp-amp-cpp-accelerated-massive-parallelism.md",
"redirect_url": "/previous-versions/cpp/parallel/amp/cpp-amp-cpp-accelerated-massive-parallelism",
diff --git a/docs/assembler/masm/at-unwindversion.md b/docs/assembler/masm/at-unwindversion.md
new file mode 100644
index 00000000000..388cfd802e7
--- /dev/null
+++ b/docs/assembler/masm/at-unwindversion.md
@@ -0,0 +1,60 @@
+---
+description: "Learn more about: @UnwindVersion"
+title: "@UnwindVersion"
+ms.date: 05/07/2026
+f1_keywords: ["@UnwindVersion"]
+helpviewer_keywords: ["@UnwindVersion symbol"]
+ai-usage: ai-assisted
+---
+# \@UnwindVersion
+
+A predefined macro that returns the unwind version the `.asm` file is being assembled with.
+
+## Syntax
+
+> **\@UnwindVersion**
+
+## Remarks
+
+> [!IMPORTANT]
+> This symbol is experimental and is subject to change. Enable Unwind Version 3 with `ml64.exe /unwindv3`.
+
+**\@UnwindVersion** is set to the unwind version used by the assembler. When `/unwindv3` is passed to `ml64.exe`, **\@UnwindVersion** is set to `3`; otherwise it's set to `1`.
+
+Use this macro with conditional assembly directives such as `IF` to assemble different code paths depending on the unwind version.
+
+This example is intended to be assembled only as it doesn't define an application entry point:
+
+## Example for unwindv3
+
+```asm
+; ml64 /c /unwindv3 ex1.asm
+.code
+
+IF @UnwindVersion EQ 3
+
+foo PROC FRAME
+ .pushreg r12
+ push r12
+
+ .endprolog
+
+ mov rax, 0
+
+ .beginepilog
+ .popreg r12
+ pop r12
+ .endepilog
+ ret
+foo ENDP
+ELSE
+ .ERR <@UnwindVersion should be 3>
+ENDIF
+
+END
+```
+
+## See also
+
+[x64 Unwind Version 3 (experimental)](directives-reference.md#x64-unwind-version-3-experimental)\
+[MASM BNF Grammar](masm-bnf-grammar.md)
diff --git a/docs/assembler/masm/directives-reference.md b/docs/assembler/masm/directives-reference.md
index c9f7208c7d7..97de3fcad7a 100644
--- a/docs/assembler/masm/directives-reference.md
+++ b/docs/assembler/masm/directives-reference.md
@@ -4,7 +4,7 @@ title: "Directives Reference"
ms.date: 07/15/2020
f1_keywords: ["Directives Reference"]
helpviewer_keywords: ["MASM (Microsoft Macro Assembler), directives reference"]
-ms.assetid: da6efcd1-18f7-41de-81cd-a002a02f9a22
+ai-usage: ai-assisted
---
# Directives Reference
@@ -27,6 +27,49 @@ ms.assetid: da6efcd1-18f7-41de-81cd-a002a02f9a22
:::column-end:::
:::row-end:::
+## x64 Unwind Version 3 (experimental)
+
+The following directives are used with `ml64.exe` when the `/unwindv3` option is enabled. Unwind Version 3 is experimental and is subject to change.
+
+**Prologue directives**
+
+:::row:::
+ :::column span="":::
+ [`.ALLOCSTACK`](dot-allocstack.md)\
+ [`.ENDPROLOG`](dot-endprolog.md)\
+ [`.PUSH2REG`](dot-push2reg.md)
+ :::column-end:::
+ :::column span="":::
+ [`.PUSHFRAME`](dot-pushframe.md)\
+ [`.PUSHREG`](dot-pushreg.md)\
+ [`.SAVEREG`](dot-savereg.md)
+ :::column-end:::
+ :::column span="":::
+ [`.SAVEXMM128`](dot-savexmm128.md)\
+ [`.SETFRAME`](dot-setframe.md)
+ :::column-end:::
+:::row-end:::
+
+**Epilogue directives**
+
+:::row:::
+ :::column span="":::
+ [`.BEGINEPILOG`](dot-beginepilog.md)\
+ [`.ENDEPILOG`](dot-endepilog.md)\
+ [`.FREESTACK`](dot-freestack.md)
+ :::column-end:::
+ :::column span="":::
+ [`.POP2REG`](dot-pop2reg.md)\
+ [`.POPFRAME`](dot-popframe.md)\
+ [`.POPREG`](dot-popreg.md)\
+ [`.RESTOREREG`](dot-restorereg.md)
+ :::column-end:::
+ :::column span="":::
+ [`.RESTOREXMM128`](dot-restorexmm128.md)\
+ [`.UNSETFRAME`](dot-unsetframe.md)
+ :::column-end:::
+:::row-end:::
+
## Code Labels
:::row:::
diff --git a/docs/assembler/masm/dot-allocstack.md b/docs/assembler/masm/dot-allocstack.md
index 13c5e6e1146..6d0881627bd 100644
--- a/docs/assembler/masm/dot-allocstack.md
+++ b/docs/assembler/masm/dot-allocstack.md
@@ -1,39 +1,41 @@
---
description: "Learn more about: .ALLOCSTACK"
title: ".ALLOCSTACK"
-ms.date: "12/17/2019"
+ms.date: 05/11/2026
f1_keywords: [".ALLOCSTACK"]
helpviewer_keywords: [".ALLOCSTACK directive"]
-ms.assetid: 9801594b-7ac2-4df2-a49d-07d9dd9af99e
+ai-usage: ai-assisted
---
# .ALLOCSTACK
-Generates a **UWOP_ALLOC_SMALL** or a **UWOP_ALLOC_LARGE** with the specified size for the current offset in the prologue.
+`.ALLOCSTACK` generates a **UWOP_ALLOC_SMALL** or a **UWOP_ALLOC_LARGE** with the specified size for the current offset in the prologue.
## Syntax
-> **.ALLOCSTACK** *size*
+> `.ALLOCSTACK` *size*
## Remarks
-MASM will choose the most efficient encoding for a given size.
+Microsoft Assembler (MASM) chooses the most efficient encoding for a given size.
-**.ALLOCSTACK** allows ml64.exe users to specify how a frame function unwinds and is only allowed within the prologue, which extends from the [PROC](proc.md) FRAME declaration to the [.ENDPROLOG](dot-endprolog.md) directive. These directives do not generate code; they only generate `.xdata` and `.pdata`. **.ALLOCSTACK** should be preceded by instructions that actually implement the actions to be unwound. It is a good practice to wrap both the unwind directives and the code they are meant to unwind in a macro to ensure agreement.
+`.ALLOCSTACK` allows `ml64.exe` users to specify how a frame function unwinds and is only allowed within the prologue, which extends from the [PROC](proc.md) `FRAME` declaration to the [.ENDPROLOG](dot-endprolog.md) directive.
+- These directives generate unwind metadata (`.xdata` and `.pdata` sections) but don't produce executable code.
+- Precede `.ALLOCSTACK` with the instructions that actually implement the actions to be unwound. Wrap both the unwind directives and the code they're meant to unwind in a macro to ensure agreement.
The *size* operand must be a multiple of 8.
-For more information, see [MASM for x64 (ml64.exe)](masm-for-x64-ml64-exe.md).
+The epilogue counterpart is [.FREESTACK](dot-freestack.md).
-## Sample
+## Example: specify an unwind version 3 unwind/exception handler
The following sample shows how to specify an unwind/exception handler:
```asm
-; ml64 ex3.asm /link /entry:Example1 /SUBSYSTEM:Console
+; ml64 ex3.asm /link /entry:Example3 /SUBSYSTEM:Console
text SEGMENT
PUBLIC Example3
PUBLIC Example3_UW
-Example3_UW PROC NEAR
+Example3_UW PROC
; exception/unwind handler body
ret 0
@@ -56,7 +58,61 @@ text ENDS
END
```
+## Unwind Version 3 behavior
+
+> [!IMPORTANT]
+> Unwind Version 3 support is experimental and is subject to change. Enable it by using `ml64.exe /unwindv3`.
+
+`.ALLOCSTACK` generates a `WOD_ALLOC_SMALL`, `WOD_ALLOC_LARGE`, or `WOD_ALLOC_HUGE` Unwind Version 3 unwind code entry with the specified size for the current offset in the prolog.
+
+`.ALLOCSTACK` must appear **before** the `sub rsp, N` instruction it describes. This requirement is the opposite of Version 1, where the directive follows the instruction.
+
+MASM emits one of three unwind codes depending on the allocation size:
+
+| Unwind code | Condition |
+|---|---|
+| `WOD_ALLOC_SMALL` | *size* ≤ 128 bytes |
+| `WOD_ALLOC_LARGE` | *size* ≤ 32 KB |
+| `WOD_ALLOC_HUGE` | *size* > 32 KB |
+
+Version 1 generates only `UWOP_ALLOC_SMALL` or `UWOP_ALLOC_LARGE`. Version 3 adds a third variant, `WOD_ALLOC_HUGE`, for allocations larger than 32 KB.
+
+> [!NOTE]
+> In Unwind Version 1, the directive appears after the corresponding instruction. In Unwind Version 3, the directive appears **before** the instruction.
+
+### Example for unwindv3
+
+```asm
+; ml64 ex3.asm /unwindv3 /link /entry:Example3 /SUBSYSTEM:Console
+text SEGMENT
+PUBLIC Example3
+PUBLIC Example3_UW
+Example3_UW PROC
+ ; exception/unwind handler body
+
+ ret 0
+
+Example3_UW ENDP
+
+Example3 PROC FRAME : Example3_UW
+
+.allocstack 16
+ sub rsp, 16
+
+.endprolog
+
+ ; function body
+ add rsp, 16
+ ret 0
+
+Example3 ENDP
+text ENDS
+END
+```
+
## See also
+[x64 Unwind Version 3 (experimental)](directives-reference.md#x64-unwind-version-3-experimental)\
[Directives Reference](directives-reference.md)\
-[MASM BNF Grammar](masm-bnf-grammar.md)
+[MASM BNF Grammar](masm-bnf-grammar.md)\
+[MASM for x64 (ml64.exe)](masm-for-x64-ml64-exe.md)
\ No newline at end of file
diff --git a/docs/assembler/masm/dot-beginepilog.md b/docs/assembler/masm/dot-beginepilog.md
new file mode 100644
index 00000000000..9f05bcdaf1d
--- /dev/null
+++ b/docs/assembler/masm/dot-beginepilog.md
@@ -0,0 +1,59 @@
+---
+description: "Learn more about: .BEGINEPILOG"
+title: ".BEGINEPILOG"
+ms.date: 05/04/2026
+ai-usage: ai-assisted
+f1_keywords: [".BEGINEPILOG"]
+helpviewer_keywords: [".BEGINEPILOG directive"]
+---
+# .BEGINEPILOG
+
+Marks the start of an epilogue unwind region. This directive doesn't emit an Unwind Operation Descriptors (WOD) code.
+
+## Syntax
+
+> `.BEGINEPILOG`
+
+## Remarks
+
+> [!IMPORTANT]
+> This directive is experimental and is subject to change.
+> Enable Unwind Version 3 by using `ml64.exe /unwindv3`.
+
+`.BEGINEPILOG` is only valid in Unwind Version 3.
+
+- It marks the start of an epilogue region where epilogue unwind operations are recorded. Pair `.BEGINEPILOG` with a closing [.ENDEPILOG](dot-endepilog.md) or no epilog unwind codes are emitted.
+- In Unwind Version 3, epilog directives are mandatory for epilog unwind code generation.
+- Epilogues must contain at least one directive.
+- These directives generate unwind metadata (`.xdata` and `.pdata` sections) but don't produce executable code.
+
+> [!NOTE]
+> In Unwind Version 1, the directive appears after the corresponding instruction. In Unwind Version 3, the directive appears **before** the instruction.
+
+## Example for unwindv3
+
+```asm
+; ml64 /unwindv3 ex1.asm /link /entry:Example1 /SUBSYSTEM:CONSOLE
+_text SEGMENT
+Example1 PROC FRAME
+ .allocstack 16
+ sub rsp, 16
+.endprolog
+ ; function body
+ .beginepilog
+ .freestack 16
+ add rsp, 16
+ .endepilog
+ ret
+Example1 ENDP
+_text ENDS
+END
+```
+
+## See also
+
+[x64 Unwind Version 3 (experimental)](directives-reference.md#x64-unwind-version-3-experimental)\
+[Directives Reference](directives-reference.md)\
+[.ENDEPILOG](dot-endepilog.md)\
+[.ENDPROLOG](dot-endprolog.md)\
+[MASM BNF Grammar](masm-bnf-grammar.md)
diff --git a/docs/assembler/masm/dot-endepilog.md b/docs/assembler/masm/dot-endepilog.md
new file mode 100644
index 00000000000..af9383ae19e
--- /dev/null
+++ b/docs/assembler/masm/dot-endepilog.md
@@ -0,0 +1,60 @@
+---
+description: "Learn more about: .ENDEPILOG"
+title: ".ENDEPILOG"
+ms.date: "04/29/2026"
+ai-usage: ai-assisted
+f1_keywords: [".ENDEPILOG"]
+helpviewer_keywords: [".ENDEPILOG directive"]
+---
+# .ENDEPILOG
+
+Marks the end of an epilogue unwind region. This directive doesn't emit a Windows unwind data (WOD) unwind code.
+
+## Syntax
+
+> **.ENDEPILOG**
+
+## Remarks
+
+> [!IMPORTANT]
+> This directive is experimental and is subject to change.
+> Enable Unwind Version 3 by using `ml64.exe /unwindv3`.
+
+**.ENDEPILOG** is only valid in Unwind Version 3.
+
+- It marks the end of an epilogue region started by [.BEGINEPILOG](dot-beginepilog.md).
+- These directives generate unwind metadata (`.xdata` and `.pdata` sections) but don't produce executable code.
+- Epilogues must contain at least one directive.
+- Epilogue directives are mandatory for epilogue unwind code generation. No epilogue unwind codes are emitted without a `.BEGINEPILOG`/`.ENDEPILOG` pair.
+- It's an error to use epilogue directives outside of the region between [.BEGINEPILOG](dot-beginepilog.md) and **.ENDEPILOG**.
+
+> [!NOTE]
+> In Unwind Version 1, the directive appears after the corresponding instruction. In Unwind Version 3, the directive appears **before** the instruction.
+
+## Example
+
+```asm
+; ml64 /unwindv3 ex1.asm /link /entry:Example1 /SUBSYSTEM:CONSOLE
+_text SEGMENT
+Example1 PROC FRAME
+ .allocstack 16
+ sub rsp, 16
+.endprolog
+ ; function body
+ .beginepilog
+ .freestack 16
+ add rsp, 16
+ .endepilog
+ ret
+Example1 ENDP
+_text ENDS
+END
+```
+
+## See also
+
+[x64 Unwind Version 3 (experimental)](directives-reference.md#x64-unwind-version-3-experimental)\
+[Directives Reference](directives-reference.md)\
+[.BEGINEPILOG](dot-beginepilog.md)\
+[.ENDPROLOG](dot-endprolog.md)\
+[MASM BNF Grammar](masm-bnf-grammar.md)
diff --git a/docs/assembler/masm/dot-endprolog.md b/docs/assembler/masm/dot-endprolog.md
index c864e0c8494..bc366ab72e5 100644
--- a/docs/assembler/masm/dot-endprolog.md
+++ b/docs/assembler/masm/dot-endprolog.md
@@ -1,14 +1,14 @@
---
description: "Learn more about: .ENDPROLOG"
title: ".ENDPROLOG"
-ms.date: "12/17/2019"
+ms.date: 05/06/2026
f1_keywords: [".ENDPROLOG"]
helpviewer_keywords: [".ENDPROLOG directive"]
-ms.assetid: 61a2474c-9527-46e6-9f9d-bc4b42c10f35
+ai-usage: ai-assisted
---
# .ENDPROLOG
-Signals the end of the prologue declarations.
+Marks the end of the prologue declarations.
## Syntax
@@ -16,11 +16,22 @@ Signals the end of the prologue declarations.
## Remarks
-It is an error to use any of the prologue declarations outside of the region between [PROC](proc.md) **FRAME** and **.ENDPROLOG**.
+It's an error to use any of the prologue declarations outside of the region between [PROC](proc.md) `FRAME` and **.ENDPROLOG**.
For more information, see [MASM for x64 (ml64.exe)](masm-for-x64-ml64-exe.md).
+## Unwind Version 3 behavior
+
+> [!IMPORTANT]
+> Unwind Version 3 support is experimental and is subject to change.
+> Enable it with `ml64.exe /unwindv3`.
+
+`.ENDPROLOG` is also used in Unwind Version 3 and continues to mark the end of the function prologue. It doesn't generate a Windows unwind data (WOD) unwind code entry.
+
+It's an error to use any prologue directive outside the region between `PROC FRAME` and `.ENDPROLOG`.
+
## See also
+[x64 Unwind Version 3 (experimental)](directives-reference.md#x64-unwind-version-3-experimental)\
[Directives Reference](directives-reference.md)\
[MASM BNF Grammar](masm-bnf-grammar.md)
diff --git a/docs/assembler/masm/dot-freestack.md b/docs/assembler/masm/dot-freestack.md
new file mode 100644
index 00000000000..bf80a2be682
--- /dev/null
+++ b/docs/assembler/masm/dot-freestack.md
@@ -0,0 +1,74 @@
+---
+description: "Learn more about: .FREESTACK"
+title: ".FREESTACK"
+ms.date: 05/06/2026
+f1_keywords: [".FREESTACK"]
+helpviewer_keywords: [".FREESTACK directive"]
+ai-usage: ai-assisted
+---
+# .FREESTACK
+
+Generates a **WOD_ALLOC_SMALL**, **WOD_ALLOC_LARGE**, or **WOD_ALLOC_HUGE** unwind code entry with the specified size for the current offset in the epilogue.
+
+## Syntax
+
+> **.FREESTACK** *size*
+
+## Parameters
+
+*size*\
+The number of bytes to deallocate from the stack. Must be a multiple of 8.
+
+## Remarks
+
+> [!IMPORTANT]
+> This directive is experimental and is subject to change.
+> Enable Unwind Version 3 by using `ml64.exe /unwindv3`.
+
+- You can use **.FREESTACK** only in Unwind Version 3. It's the epilogue counterpart to [.ALLOCSTACK](dot-allocstack.md).
+- You can use **.FREESTACK** only within an epilogue region, between [.BEGINEPILOG](dot-beginepilog.md) and [.ENDEPILOG](dot-endepilog.md).
+- In Unwind Version 3, **.FREESTACK** must appear **before** the `add rsp, N` instruction that implements the stack deallocation.
+- To ensure agreement, wrap both the unwind directives and the code they're meant to unwind in a macro.
+- These directives generate unwind metadata (`.xdata` and `.pdata` sections) but don't produce executable code.
+- Microsoft Assembler (MASM) chooses the most efficient encoding for a given size.
+
+MASM emits one of three unwind codes depending on the size:
+
+| Unwind code | Condition |
+|---|---|
+| `WOD_ALLOC_SMALL` | *size* ≤ 128 bytes |
+| `WOD_ALLOC_LARGE` | *size* ≤ 32 KB |
+| `WOD_ALLOC_HUGE` | *size* > 32 KB |
+
+In Unwind Version 3, epilogue directives are mandatory for epilogue unwind code generation. The assembler doesn't emit epilogue unwind codes without a `.BEGINEPILOG`/`.ENDEPILOG` pair.
+
+> [!NOTE]
+> In Unwind Version 1, the directive appears after the corresponding instruction. In Unwind Version 3, the directive appears **before** the instruction.
+
+## Example for unwindv3
+
+```asm
+; ml64 /unwindv3 ex1.asm /link /entry:Example1 /SUBSYSTEM:CONSOLE
+_text SEGMENT
+Example1 PROC FRAME
+ .allocstack 16
+ sub rsp, 16
+.endprolog
+ ; function body
+ .beginepilog
+ .freestack 16
+ add rsp, 16
+ .endepilog
+ ret
+Example1 ENDP
+_text ENDS
+END
+```
+
+## See also
+
+[x64 Unwind Version 3 (experimental)](directives-reference.md#x64-unwind-version-3-experimental)\
+[Directives Reference](directives-reference.md)\
+[.ALLOCSTACK](dot-allocstack.md)\
+[.BEGINEPILOG](dot-beginepilog.md)\
+[MASM BNF Grammar](masm-bnf-grammar.md)
diff --git a/docs/assembler/masm/dot-pop2reg.md b/docs/assembler/masm/dot-pop2reg.md
new file mode 100644
index 00000000000..56dbdff4b52
--- /dev/null
+++ b/docs/assembler/masm/dot-pop2reg.md
@@ -0,0 +1,76 @@
+---
+description: "Learn more about: .POP2REG"
+title: ".POP2REG"
+ms.date: 05/04/2026
+f1_keywords: [".POP2REG"]
+helpviewer_keywords: [".POP2REG directive"]
+ai-usage: ai-assisted
+---
+# .POP2REG
+
+Generates a two-register pop unwind code entry for the specified register pair using the current offset in the epilogue.
+
+## Syntax
+
+> **.POP2REG** *register1*, *register2*
+
+## Parameters
+
+*register1*\
+The first register to pop. Must be a general-purpose 64-bit register.
+
+*register2*\
+The second register to pop. Must be a general-purpose 64-bit register.
+
+*register1* and *register2* may each be one of:\
+`RAX, RCX, RDX, RBX, RDI, RSI, RBP, R8, R9, R10, R11, R12, R13, R14, R15, R16, R17, R18, R19, R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R31`.
+
+## Remarks
+
+> [!IMPORTANT]
+> This directive is experimental and is subject to change. Enable Unwind Version 3 with `ml64.exe /unwindv3`.
+
+- **.POP2REG** is only valid in Unwind Version 3. It's the epilogue counterpart to [.PUSH2REG](dot-push2reg.md).
+- **.POP2REG** is only allowed within an epilogue region, between [.BEGINEPILOG](dot-beginepilog.md) and [.ENDEPILOG](dot-endepilog.md).
+- These directives generate unwind metadata (`.xdata` and `.pdata` sections) but don't produce executable code.
+- In Unwind Version 3, **.POP2REG** must appear **before** the instruction that actually implements the action to be unwound.
+- In Unwind Version 3, epilogue directives are mandatory for epilogue unwind code generation. No epilogue unwind codes are emitted without a `.BEGINEPILOG`/`.ENDEPILOG` pair.
+- To ensure agreement, wrap both the unwind directives and the code they're meant to unwind in a macro.
+
+If *register1* and *register2* are consecutive and in increasing order, MASM emits a `WOD_PUSH_CONSECUTIVE_2` unwind code. Otherwise, MASM emits a `WOD_PUSH2` unwind code.
+
+> [!NOTE]
+> In Unwind Version 1, the directive appears after the corresponding instruction. In Unwind Version 3, the directive appears **before** the instruction.
+
+## Example
+
+```asm
+; ml64 /unwindv3 ex1.asm /link /entry:Example1 /SUBSYSTEM:CONSOLE
+_text SEGMENT
+Example1 PROC FRAME
+ .push2reg rbx, rsi
+ push2 rbx, rsi
+ .push2reg r10, r11
+ push2 r10, r11
+.endprolog
+ ; rest of function ...
+ .beginepilog
+ .pop2reg r10, r11
+ pop2 r10, r11
+ .pop2reg rbx, rsi
+ pop2 rbx, rsi
+ .endepilog
+ ret
+Example1 ENDP
+_text ENDS
+END
+```
+
+## See also
+
+[x64 Unwind Version 3 (experimental)](directives-reference.md#x64-unwind-version-3-experimental)\
+[Directives Reference](directives-reference.md)\
+[.PUSH2REG](dot-push2reg.md)\
+[.POPREG](dot-popreg.md)\
+[.BEGINEPILOG](dot-beginepilog.md)\
+[MASM BNF Grammar](masm-bnf-grammar.md)
diff --git a/docs/assembler/masm/dot-popframe.md b/docs/assembler/masm/dot-popframe.md
new file mode 100644
index 00000000000..6f0d869f13d
--- /dev/null
+++ b/docs/assembler/masm/dot-popframe.md
@@ -0,0 +1,74 @@
+---
+description: "Learn more about: .POPFRAME"
+title: ".POPFRAME"
+ms.date: 05/01/2026
+f1_keywords: [".POPFRAME"]
+helpviewer_keywords: [".POPFRAME directive"]
+ai-usage: ai-assisted
+---
+# .POPFRAME
+
+Generates a `WOD_PUSH_CANONICAL_FRAME` Windows unwind data (WOD) unwind code entry in the epilogue.
+
+## Syntax
+
+> **.POPFRAME** ⟦**CODE** | *value*⟧
+
+## Parameters
+
+*value*\
+An optional numeric modifier in the range 0–255.\
+Mutually exclusive with **CODE**. If you specify the optional **CODE** keyword, the unwind code entry receives a modifier of 1.\
+If you specify an optional numeric *value* instead, it receives the specified value.\
+If you don't pass an argument, the value is 0.
+
+## Remarks
+
+> [!IMPORTANT]
+> This directive is experimental and is subject to change. Enable Unwind Version 3 with `ml64.exe /unwindv3`.
+
+The **.POPFRAME** directive lets `ml64.exe` users specify how a frame function unwinds in an epilog. You can only use it within an epilog region, between [.BEGINEPILOG](dot-beginepilog.md) and [.ENDEPILOG](dot-endepilog.md).
+
+- **.POPFRAME** is only valid in Unwind Version 3. It's the epilog counterpart of [.PUSHFRAME](dot-pushframe.md). The operand value should match the corresponding **.PUSHFRAME** in the prologue.
+- In Unwind Version 3, **.POPFRAME** must appear **before** the instruction that implements the action to be unwound. To ensure agreement, wrap both the unwind directives and the code they're meant to unwind in a macro.
+- In Unwind Version 3, epilogue directives are mandatory for epilogue unwind code generation. No epilogue unwind codes are emitted without a `.BEGINEPILOG`/`.ENDEPILOG` pair.
+- These directives generate unwind metadata (`.xdata` and `.pdata` sections) but don't produce executable code.
+
+> [!NOTE]
+> In Unwind Version 1, directives appear after the corresponding instruction. In Unwind Version 3, directives appear **before** the instruction.
+
+## Example for unwindv3
+
+The following example shows how to use **.POPFRAME** in an epilogue to indicate an interrupt handler that pushes and pops a canonical machine frame.
+
+```asm
+; ml64 /unwindv3 ex1.asm /link /entry:Example1 /SUBSYSTEM:CONSOLE
+_text SEGMENT
+Example1 PROC FRAME
+ .pushframe
+ .pushreg rbx
+ push rbx
+ .allocstack 32
+ sub rsp, 32
+.endprolog
+ ; interrupt handler body ...
+ .beginepilog
+ .freestack 32
+ add rsp, 32
+ .popreg rbx
+ pop rbx
+ .popframe
+ .endepilog
+ iretq
+Example1 ENDP
+_text ENDS
+END
+```
+
+## See also
+
+[x64 Unwind Version 3 (experimental)](directives-reference.md#x64-unwind-version-3-experimental)\
+[.PUSHFRAME](dot-pushframe.md)\
+[.BEGINEPILOG](dot-beginepilog.md)\
+[.ENDEPILOG](dot-endepilog.md)\
+[MASM BNF Grammar](masm-bnf-grammar.md)
diff --git a/docs/assembler/masm/dot-popreg.md b/docs/assembler/masm/dot-popreg.md
new file mode 100644
index 00000000000..963e7de0f48
--- /dev/null
+++ b/docs/assembler/masm/dot-popreg.md
@@ -0,0 +1,70 @@
+---
+description: "Learn more about: .POPREG"
+title: ".POPREG"
+ms.date: 05/04/2026
+f1_keywords: [".POPREG"]
+helpviewer_keywords: [".POPREG directive"]
+ai-usage: ai-assisted
+---
+# .POPREG
+
+Generates a `WOD_PUSH` unwind code entry for the specified register using the current offset in the epilogue.
+
+## Syntax
+
+> .POPREG *register*
+
+## Parameters
+
+*register*\
+The register to pop. Must be a general-purpose 64-bit register.
+
+## Remarks
+
+> [!IMPORTANT]
+> This directive is experimental and is subject to change. Enable Unwind Version 3 by using the `/unwindv3` option in ml64.exe.
+
+`.POPREG` is only valid in Unwind Version 3. It's the epilogue counterpart to [.PUSHREG](dot-pushreg.md).
+
+`.POPREG` is only allowed within an epilogue region, between [.BEGINEPILOG](dot-beginepilog.md) and [.ENDEPILOG](dot-endepilog.md). These directives generate unwind metadata (`.xdata` and `.pdata` sections) but don't produce executable code. In Unwind Version 3, `.POPREG` must appear **before** the `pop` instruction that implements the register restore. To ensure agreement, wrap both the unwind directives and the code they're meant to unwind in a macro.
+
+*register* may be one of:\
+`RAX, RCX, RDX, RBX, RDI, RSI, RBP, R8, R9, R10, R11, R12, R13, R14, R15, R16, R17, R18, R19, R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R31`
+
+In Unwind Version 3, epilogue directives are mandatory for epilogue unwind code generation. The assembler doesn't emit epilogue unwind codes without a `.BEGINEPILOG`/`.ENDEPILOG` pair.
+
+> [!NOTE]
+> In Unwind Version 1, the directive appears after the corresponding instruction. In Unwind Version 3, the directive appears **before** the instruction.
+
+## Example for unwindv3
+
+```asm
+; ml64 /unwindv3 ex1.asm /link /entry:Example1 /SUBSYSTEM:CONSOLE
+_text SEGMENT
+Example1 PROC FRAME
+ .pushreg rbx
+ push rbx
+ .pushreg rsi
+ push rsi
+.endprolog
+ ; rest of function ...
+ .beginepilog
+ .popreg rsi
+ pop rsi
+ .popreg rbx
+ pop rbx
+ .endepilog
+ ret
+Example1 ENDP
+_text ENDS
+END
+```
+
+## See also
+
+[x64 Unwind Version 3 (experimental)](directives-reference.md#x64-unwind-version-3-experimental)\
+[Directives Reference](directives-reference.md)\
+[.PUSHREG](dot-pushreg.md)\
+[.POP2REG](dot-pop2reg.md)\
+[.BEGINEPILOG](dot-beginepilog.md)\
+[MASM BNF Grammar](masm-bnf-grammar.md)
diff --git a/docs/assembler/masm/dot-push2reg.md b/docs/assembler/masm/dot-push2reg.md
new file mode 100644
index 00000000000..d43e1113271
--- /dev/null
+++ b/docs/assembler/masm/dot-push2reg.md
@@ -0,0 +1,65 @@
+---
+description: "Learn more about: .PUSH2REG"
+title: ".PUSH2REG"
+ms.date: 05/04/2026
+f1_keywords: [".PUSH2REG"]
+helpviewer_keywords: [".PUSH2REG directive"]
+ai-usage: ai-assisted
+---
+# .PUSH2REG
+
+Generates a two-register push unwind code entry for the specified register pair using the current offset in the prologue.
+
+## Syntax
+
+> `.PUSH2REG` *register1*, *register2*
+
+## Parameters
+
+*register1*\
+The first register to push. Must be a general-purpose 64-bit register.
+
+*register2*\
+The second register to push. Must be a general-purpose 64-bit register.
+
+*register1* and *register2* may each be one of:\
+`RAX, RCX, RDX, RBX, RDI, RSI, RBP, R8, R9, R10, R11, R12, R13, R14, R15, R16, R17, R18, R19, R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R31.`
+
+## Remarks
+
+> [!IMPORTANT]
+> This directive is experimental and is subject to change. Enable Unwind Version 3 by using `ml64.exe /unwindv3`.
+
+- Use `.PUSH2REG` to specify how a frame function unwinds. You can only use this directive within the prologue, which extends from the [PROC](proc.md) `FRAME` declaration to the [.ENDPROLOG](dot-endprolog.md) directive.
+- These directives generate unwind metadata (`.xdata` and `.pdata` sections) but don't produce executable code. In Unwind Version 3, `.PUSH2REG` must appear **before** the instruction that actually implements the action to be unwound. To ensure agreement, it's a good practice to wrap both the unwind directives and the code they're meant to unwind in a macro.
+- If *register1* and *register2* are consecutive and in increasing order, MASM emits a `WOD_PUSH_CONSECUTIVE_2` unwind code. Otherwise, MASM emits a `WOD_PUSH2` unwind code.
+
+> [!NOTE]
+> In Unwind Version 1, the directive appears after the corresponding instruction. In Unwind Version 3, the directive appears **before** the instruction.
+
+## Example for unwindv3
+
+```asm
+; ml64 /unwindv3 ex1.asm /link /entry:Example1 /SUBSYSTEM:CONSOLE
+_text SEGMENT
+Example1 PROC FRAME
+ .push2reg r10, r11
+ push2 r10, r11
+ .push2reg rbx, rsi
+ push2 rbx, rsi
+.endprolog
+ ; rest of function ...
+ ret
+Example1 ENDP
+_text ENDS
+END
+```
+
+## See also
+
+[x64 Unwind Version 3 (experimental)](directives-reference.md#x64-unwind-version-3-experimental)\
+[Directives Reference](directives-reference.md)\
+[.POP2REG](dot-pop2reg.md)\
+[.PUSHREG](dot-pushreg.md)\
+[.ENDPROLOG](dot-endprolog.md)\
+[MASM BNF Grammar](masm-bnf-grammar.md)
diff --git a/docs/assembler/masm/dot-pushframe.md b/docs/assembler/masm/dot-pushframe.md
index 07dc3972dfc..da3d77c596f 100644
--- a/docs/assembler/masm/dot-pushframe.md
+++ b/docs/assembler/masm/dot-pushframe.md
@@ -4,23 +4,58 @@ description: "Describes the .PUSHFRAME MASM directive, used to specify how to un
ms.date: "12/06/2019"
f1_keywords: [".PUSHFRAME"]
helpviewer_keywords: [".PUSHFRAME directive"]
-ms.assetid: 17b123d0-4c6d-4fd2-85eb-798e8ad0a73c
+ai-usage: ai-assisted
---
# .PUSHFRAME
-Generates a `UWOP_PUSH_MACHFRAME` unwind code entry. If the optional **CODE** keyword is specified, the unwind code entry is given a modifier of 1. Otherwise the modifier is 0.
+Generates a `UWOP_PUSH_MACHFRAME` unwind code entry. If you specify the optional **CODE** keyword, the unwind code entry gets a modifier of 1. Otherwise, the modifier is 0.
## Syntax
-> **.PUSHFRAME** ⟦**CODE**⟧;;
+> `.PUSHFRAME` ⟦**CODE**⟧ ;Prior to Unwind Version 3
+> `.PUSHFRAME` ⟦**CODE**⟧ | [0-255] ;Unwind Version 3 specific
## Remarks
-.PUSHFRAME allows ml64.exe users to specify how a frame function unwinds. It's only allowed within the prologue, which extends from the [PROC](proc.md) FRAME declaration to the [.ENDPROLOG](dot-endprolog.md) directive. These directives don't generate code; they only generate `.xdata` and `.pdata`. **.PUSHFRAME** should be preceded by instructions that actually implement the actions to be unwound. It's a good practice to wrap both the unwind directives and the code they're meant to unwind in a macro to ensure agreement.
+Use `.PUSHFRAME` with `ml64.exe` to specify how a frame function unwinds. You can only use it within the prologue, which extends from the [PROC](proc.md) `FRAME` declaration to the [.ENDPROLOG](dot-endprolog.md) directive.
+- These directives generate unwind metadata (`.xdata` and `.pdata` sections) but don't produce executable code.
+- Precede `.PUSHFRAME` with the instructions that implement the actions to be unwound.
+- To ensure agreement, wrap both the unwind directives and the code they're meant to unwind in a macro.
-For more information, see [MASM for x64 (ml64.exe)](masm-for-x64-ml64-exe.md).
+## Unwind Version 3 behavior
+
+> [!IMPORTANT]
+> Unwind Version 3 support is experimental and is subject to change. Enable it by using `ml64.exe /unwindv3`.
+
+In Unwind Version 3, `.PUSHFRAME` emits a `WOD_PUSH_CANONICAL_FRAME` unwind code entry.\
+When you specify the optional **CODE** keyword, the unwind code entry modifier value is 1.\
+If you specify an optional *value*, the directive uses it directly.\
+If you don't pass an argument, the value is 0. The *value* must be in the range 0–255.
+
+> **Note:** In Unwind Version 1 the directives come after the instruction. In Unwind Version 3, the directives come before the instruction.
+> `.PUSHFRAME` must appear **before** the instruction it describes. This behavior is the opposite of Version 1, where the directive follows the instruction.
+
+### Example for unwindv3
+
+```asm
+; ml64 /unwindv3 ex1.asm /link /entry:Example1 /SUBSYSTEM:CONSOLE
+_text SEGMENT
+Example1 PROC FRAME
+ .pushframe CODE
+.endprolog
+ ; interrupt handler body ...
+ iretq
+Example1 ENDP
+_text ENDS
+END
+```
+
+The epilogue counterpart is [.POPFRAME](dot-popframe.md).
## See also
+[x64 Unwind Version 3 (experimental)](directives-reference.md#x64-unwind-version-3-experimental)\
[Directives reference](directives-reference.md)\
-[MASM BNF Grammar](masm-bnf-grammar.md)
+[.POPFRAME](dot-popframe.md)\
+[MASM BNF Grammar](masm-bnf-grammar.md)\
+[MASM for x64 (ml64.exe)](masm-for-x64-ml64-exe.md)
diff --git a/docs/assembler/masm/dot-pushreg.md b/docs/assembler/masm/dot-pushreg.md
index a433f688d6e..d6a48cb5227 100644
--- a/docs/assembler/masm/dot-pushreg.md
+++ b/docs/assembler/masm/dot-pushreg.md
@@ -1,10 +1,10 @@
---
description: "Learn more about: .PUSHREG"
title: ".PUSHREG"
-ms.date: "12/16/2019"
+ms.date: 05/04/2026
f1_keywords: [".PUSHREG"]
helpviewer_keywords: [".PUSHREG directive"]
-ms.assetid: e0c83758-dfed-40ea-afe6-cb833c8d2d30
+ai-usage: ai-assisted
---
# .PUSHREG
@@ -14,23 +14,20 @@ Generates a `UWOP_PUSH_NONVOL` unwind code entry for the specified register numb
> .PUSHREG *register*
-## Remarks
-
-**.PUSHREG** allows ml64.exe users to specify how a frame function unwinds, and is only allowed within the prologue, which extends from the [PROC](proc.md) **FRAME** declaration to the [.ENDPROLOG](dot-endprolog.md) directive. These directives do not generate code; they only generate `.xdata` and `.pdata`. **.PUSHREG** should be preceded by instructions that actually implement the actions to be unwound. It is a good practice to wrap both the unwind directives and the code they are meant to unwind in a macro to ensure agreement.
-
*register* may be one of:\
-RAX | RCX | RDX | RBX | RDI | RSI | RBP | R8 | R9 | R10 | R11 | R12 | R13 | R14 | R15.
-
-For more information, see [MASM for x64 (ml64.exe)](masm-for-x64-ml64-exe.md).
+`RAX, RCX, RDX, RBX, RDI, RSI, RBP, R8, R9, R10, R11, R12, R13, R14, R15`
-## Sample
+Unwind Version 3 extends register support to include R16–R31. *register* may be one of:\
+`RAX, RCX, RDX, RBX, RDI, RSI, RBP, R8, R9, R10, R11, R12, R13, R14, R15, R16, R17, R18, R19, R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R31`
-### Description
+## Remarks
-The following sample shows how to push non-volatile registers.
+Use `.PUSHREG` with `ml64.exe` to specify how a frame function unwinds. You can only use `.PUSHREG` within the prologue, which extends from the [PROC](proc.md) `FRAME` declaration to the [.ENDPROLOG](dot-endprolog.md) directive. These directives generate unwind metadata (`.xdata` and `.pdata` sections) but don't produce executable code. Precede `.PUSHREG` with the instructions that actually implement the actions to be unwound. To ensure agreement, wrap both the unwind directives and the code they're meant to unwind in a macro.
### Code
+The following sample shows how to push nonvolatile registers.
+
```asm
; ml64 ex1.asm /link /entry:Example1 /SUBSYSTEM:CONSOLE
_text SEGMENT
@@ -51,7 +48,42 @@ _text ENDS
END
```
+## Unwind Version 3 behavior
+
+> [!IMPORTANT]
+> Unwind Version 3 support is experimental and is subject to change. Enable it by using `ml64.exe /unwindv3`.
+
+> [!NOTE]
+> In Unwind Version 1, the directive appears after the corresponding instruction. In Unwind Version 3, the directive appears **before** the instruction.
+> In Unwind Version 3, `.PUSHREG` generates a `WOD_PUSH` unwind code entry and must appear **before** the `push reg` instruction it describes. This requirement is the opposite of Version 1, where the directive follows the instruction.
+
+### Example for unwindv3
+
+```asm
+; ml64 /unwindv3 ex1.asm /link /entry:Example1 /SUBSYSTEM:CONSOLE
+_text SEGMENT
+Example1 PROC FRAME
+ .pushreg r10
+ push r10
+ .pushreg r15
+ push r15
+ .pushreg rbx
+ push rbx
+ .pushreg rsi
+ push rsi
+.endprolog
+ ; rest of function ...
+ ret
+Example1 ENDP
+_text ENDS
+END
+```
+
+The epilogue counterpart is [.POPREG](dot-popreg.md).
+
## See also
+[x64 Unwind Version 3 (experimental)](directives-reference.md#x64-unwind-version-3-experimental)\
[Directives reference](directives-reference.md)\
-[MASM BNF Grammar](masm-bnf-grammar.md)
+[MASM BNF Grammar](masm-bnf-grammar.md)\
+[MASM for x64 (ml64.exe)](masm-for-x64-ml64-exe.md)
\ No newline at end of file
diff --git a/docs/assembler/masm/dot-restorereg.md b/docs/assembler/masm/dot-restorereg.md
new file mode 100644
index 00000000000..94836c8da74
--- /dev/null
+++ b/docs/assembler/masm/dot-restorereg.md
@@ -0,0 +1,77 @@
+---
+description: "Learn more about: .RESTOREREG"
+title: ".RESTOREREG"
+ms.date: 05/04/2026
+f1_keywords: [".RESTOREREG"]
+helpviewer_keywords: [".RESTOREREG directive"]
+ai-usage: ai-assisted
+---
+# .RESTOREREG
+
+Generates either a `WOD_SAVE_NONVOL` or a `WOD_SAVE_NONVOL_FAR` unwind code entry for the specified register and offset, using the current epilogue offset.
+
+## Syntax
+
+> `.RESTOREREG` *reg*, *offset*
+
+## Parameters
+
+*reg*\
+The nonvolatile register to restore.
+
+*offset*\
+The stack offset from which the register is restored.
+
+## Remarks
+
+> [!IMPORTANT]
+> This directive is experimental and is subject to change. Enable Unwind Version 3 by using `ml64.exe /unwindv3`.
+
+`.RESTOREREG` is only valid in Unwind Version 3. It's the epilogue counterpart to [.SAVEREG](dot-savereg.md).
+
+Microsoft Assembler (MASM) chooses the most efficient encoding for a given offset.
+
+- `.RESTOREREG` is only allowed within an epilogue region, between [.BEGINEPILOG](dot-beginepilog.md) and [.ENDEPILOG](dot-endepilog.md).
+- These directives generate unwind metadata (`.xdata` and `.pdata` sections) but don't produce executable code.
+- In Unwind Version 3, `.RESTOREREG` must appear **before** the instruction that loads the register from the stack.
+- To ensure agreement, wrap both the unwind directives and the code they're meant to unwind in a macro.
+- In Unwind Version 3, epilogue directives are mandatory for epilogue unwind code generation. No epilogue unwind codes are emitted without a `.BEGINEPILOG`/`.ENDEPILOG` pair.
+
+> [!NOTE]
+> In Unwind Version 1, the directive appears after the corresponding instruction. In Unwind Version 3, the directive appears **before** the instruction.
+
+## Example for unwindv3
+
+```asm
+; ml64 /unwindv3 ex1.asm /link /entry:Example1 /SUBSYSTEM:CONSOLE
+_text SEGMENT
+Example1 PROC FRAME
+ .allocstack 020h
+ sub rsp, 020h
+ .savereg rbx, 0
+ mov [rsp], rbx
+ .savereg rsi, 8
+ mov [rsp+8], rsi
+.endprolog
+ ; rest of function ...
+ .beginepilog
+ .restorereg rsi, 8
+ mov rsi, [rsp+8]
+ .restorereg rbx, 0
+ mov rbx, [rsp]
+ .freestack 020h
+ add rsp, 020h
+ .endepilog
+ ret
+Example1 ENDP
+_text ENDS
+END
+```
+
+## See also
+
+[x64 Unwind Version 3 (experimental)](directives-reference.md#x64-unwind-version-3-experimental)\
+[Directives Reference](directives-reference.md)\
+[.SAVEREG](dot-savereg.md)\
+[.BEGINEPILOG](dot-beginepilog.md)\
+[MASM BNF Grammar](masm-bnf-grammar.md)
diff --git a/docs/assembler/masm/dot-restorexmm128.md b/docs/assembler/masm/dot-restorexmm128.md
new file mode 100644
index 00000000000..03d1bc27750
--- /dev/null
+++ b/docs/assembler/masm/dot-restorexmm128.md
@@ -0,0 +1,77 @@
+---
+description: "Learn more about: .RESTOREXMM128"
+title: ".RESTOREXMM128"
+ms.date: 05/06/2026
+f1_keywords: [".RESTOREXMM128"]
+helpviewer_keywords: [".RESTOREXMM128 directive"]
+ai-usage: ai-assisted
+---
+# .RESTOREXMM128
+
+Generates either a `WOD_SAVE_XMM128` or a `WOD_SAVE_XMM128_FAR` Unwind Version 3 unwind code entry for the specified XMM register and offset using the current epilogue offset.
+
+## Syntax
+
+> `.RESTOREXMM128` *xmmreg*, *offset*
+
+## Parameters
+
+*xmmreg*\
+The XMM register to restore.
+
+*offset*\
+The stack offset from which the register is restored. Must be a multiple of 16.
+
+## Remarks
+
+> [!IMPORTANT]
+> This directive is experimental and is subject to change. Enable Unwind Version 3 with `ml64.exe /unwindv3`.
+
+`.RESTOREXMM128` is only valid in Unwind Version 3. It's the epilogue counterpart to [.SAVEXMM128](dot-savexmm128.md).
+
+Microsoft Assembler (MASM) chooses the most efficient encoding for a given offset.
+
+- `.RESTOREXMM128` is only allowed within an epilogue region, between [.BEGINEPILOG](dot-beginepilog.md) and [.ENDEPILOG](dot-endepilog.md).
+- These directives generate unwind metadata (`.xdata` and `.pdata` sections) but don't produce executable code.
+- In Unwind Version 3, `.RESTOREXMM128` must appear **before** the instruction that loads the XMM register from the stack.
+- To ensure agreement, wrap both the unwind directives and the code they're meant to unwind in a macro.
+- In Unwind Version 3, epilogue directives are mandatory for epilogue unwind code generation. No epilogue unwind codes are emitted without a `.BEGINEPILOG`/`.ENDEPILOG` pair.
+
+> [!NOTE]
+> In Unwind Version 1, the directive appears after the corresponding instruction. In Unwind Version 3, the directive appears **before** the instruction.
+
+## Example for unwindv3
+
+```asm
+; ml64 /unwindv3 ex1.asm /link /entry:Example1 /SUBSYSTEM:CONSOLE
+_text SEGMENT
+Example1 PROC FRAME
+ .allocstack 030h
+ sub rsp, 030h
+ .savexmm128 xmm6, 0
+ movdqa [rsp], xmm6
+ .savexmm128 xmm7, 010h
+ movdqa [rsp+010h], xmm7
+.endprolog
+ ; rest of function ...
+ .beginepilog
+ .restorexmm128 xmm7, 010h
+ movdqa xmm7, [rsp+010h]
+ .restorexmm128 xmm6, 0
+ movdqa xmm6, [rsp]
+ .freestack 030h
+ add rsp, 030h
+ .endepilog
+ ret
+Example1 ENDP
+_text ENDS
+END
+```
+
+## See also
+
+[x64 Unwind Version 3 (experimental)](directives-reference.md#x64-unwind-version-3-experimental)\
+[Directives Reference](directives-reference.md)\
+[.SAVEXMM128](dot-savexmm128.md)\
+[.BEGINEPILOG](dot-beginepilog.md)\
+[MASM BNF Grammar](masm-bnf-grammar.md)
diff --git a/docs/assembler/masm/dot-savereg.md b/docs/assembler/masm/dot-savereg.md
index a786f88777f..654d19cfe57 100644
--- a/docs/assembler/masm/dot-savereg.md
+++ b/docs/assembler/masm/dot-savereg.md
@@ -1,26 +1,70 @@
---
description: "Learn more about: .SAVEREG"
title: ".SAVEREG"
-ms.date: "12/16/2019"
+ms.date: 05/06/2026
f1_keywords: [".SAVEREG"]
helpviewer_keywords: [".SAVEREG directive"]
-ms.assetid: 1dbc2ef6-a197-40e7-9e55-fddcae8cef29
+ai-usage: ai-assisted
---
# .SAVEREG
-Generates either a `UWOP_SAVE_NONVOL` or a `UWOP_SAVE_NONVOL_FAR` unwind code entry for the specified register (*reg*) and offset (*offset*) using the current prologue offset. MASM will choose the most efficient encoding.
+Generates either a `UWOP_SAVE_NONVOL` or a `UWOP_SAVE_NONVOL_FAR` unwind code entry for the specified register (*reg*) and offset (*offset*) using the current prologue offset. Microsoft Assembler (MASM) chooses the most efficient encoding.
## Syntax
-> **.SAVEREG** *reg*__,__ *offset*
+> `.SAVEREG` *reg*__,__ *offset*
## Remarks
-**.SAVEREG** allows ml64.exe users to specify how a frame function unwinds and is only allowed within the prologue, which extends from the [PROC](proc.md) FRAME declaration to the [.ENDPROLOG](dot-endprolog.md) directive. These directives do not generate code; they only generate `.xdata` and `.pdata`. **.SAVEREG** should be preceded by instructions that actually implement the actions to be unwound. It is a good practice to wrap both the unwind directives and the code they are meant to unwind in a macro to ensure agreement.
+Use `.SAVEREG` with `ml64.exe` to specify how a frame function unwinds. You can only use it within the prologue, which extends from the [`PROC`](proc.md) `FRAME` declaration to the [.ENDPROLOG](dot-endprolog.md) directive.
+- These directives generate unwind metadata (`.xdata` and `.pdata` sections) but don't produce executable code.
+- Precede `.SAVEREG` with instructions that actually implement the actions to be unwound.
+- To ensure agreement, wrap both the unwind directives and the code they're meant to unwind in a macro.
-For more information, see [MASM for x64 (ml64.exe)](masm-for-x64-ml64-exe.md).
+## Unwind Version 3 behavior
+
+> [!IMPORTANT]
+> Unwind Version 3 support is experimental and is subject to change. Enable it by using `ml64.exe /unwindv3`.
+
+In Unwind Version 3, `.SAVEREG` emits either a `WOD_SAVE_NONVOL` or a `WOD_SAVE_NONVOL_FAR` unwind code entry. MASM selects the most efficient encoding based on the size of *offset*:
+
+| Unwind code | Condition |
+|---|---|
+| `WOD_SAVE_NONVOL` | *offset* can be encoded as a scaled 16-bit value |
+| `WOD_SAVE_NONVOL_FAR` | *offset* requires a full 32-bit value |
+
+> [!NOTE]
+> In Unwind Version 1, the directive appears after the corresponding instruction. In Unwind Version 3, the directive appears **before** the instruction.
+> `.SAVEREG` must appear **before** the instruction it describes. This requirement is the opposite of Version 1, where the directive follows the instruction.
+
+### Example for unwindv3
+
+```asm
+; ml64 /unwindv3 ex1.asm /link /entry:Example1 /SUBSYSTEM:CONSOLE
+_text SEGMENT
+Example1 PROC FRAME
+ .allocstack 020h
+ sub rsp, 020h
+ .savereg rbx, 0
+ mov [rsp], rbx
+ .savereg rsi, 8
+ mov [rsp+8], rsi
+.endprolog
+ ; rest of function ...
+ mov rsi, [rsp+8]
+ mov rbx, [rsp]
+ add rsp, 020h
+ ret
+Example1 ENDP
+_text ENDS
+END
+```
+
+The epilogue counterpart is [.RESTOREREG](dot-restorereg.md).
## See also
+[x64 Unwind Version 3 (experimental)](directives-reference.md#x64-unwind-version-3-experimental)\
[Directives reference](directives-reference.md)\
+[MASM for x64 (ml64.exe)](masm-for-x64-ml64-exe.md)\
[MASM BNF Grammar](masm-bnf-grammar.md)
diff --git a/docs/assembler/masm/dot-savexmm128.md b/docs/assembler/masm/dot-savexmm128.md
index 6a914c5547f..ed2fae15341 100644
--- a/docs/assembler/masm/dot-savexmm128.md
+++ b/docs/assembler/masm/dot-savexmm128.md
@@ -1,28 +1,69 @@
---
description: "Learn more about: .SAVEXMM128"
title: ".SAVEXMM128"
-ms.date: "12/17/2019"
+ms.date: 05/04/2026
f1_keywords: [".SAVEXMM128"]
helpviewer_keywords: [".SAVEXMM128 directive"]
-ms.assetid: 551eb472-b8d0-47b1-8d82-995d1f485723
+ai-usage: ai-assisted
---
# .SAVEXMM128
-Generates either a `UWOP_SAVE_XMM128` or a `UWOP_SAVE_XMM128_FAR` unwind code entry for the specified XMM register and offset using the current prologue offset. MASM will choose the most efficient encoding.
+Generates either a `UWOP_SAVE_XMM128` or a `UWOP_SAVE_XMM128_FAR` unwind code entry for the specified XMM register and offset using the current prologue offset. Microsoft Assembler (MASM) chooses the most efficient encoding.
## Syntax
-> **.SAVEXMM128** *xmmreg* , *offset*
+> `.SAVEXMM128` *xmmreg* , *offset*
## Remarks
-**.SAVEXMM128** allows ml64.exe users to specify how a frame function unwinds, and is only allowed within the prologue, which extends from the [PROC](proc.md) FRAME declaration to the [.ENDPROLOG](dot-endprolog.md) directive. These directives do not generate code; they only generate `.xdata` and `.pdata`. .SAVEXMM128 should be preceded by instructions that actually implement the actions to be unwound. It is a good practice to wrap both the unwind directives and the code they are meant to unwind in a macro to ensure agreement.
+Use `.SAVEXMM128` with `ml64.exe` to specify how a frame function unwinds. You can only use it within the prologue, which extends from the [`PROC`](proc.md) `FRAME` declaration to the [.ENDPROLOG](dot-endprolog.md) directive. These directives generate unwind metadata (`.xdata` and `.pdata` sections) but don't produce executable code. Precede `.SAVEXMM128` by the instructions that actually implement the actions to be unwound. To ensure agreement, wrap both the unwind directives and the code they're meant to unwind in a macro.
*offset* must be a multiple of 16.
-For more information, see [MASM for x64 (ml64.exe)](masm-for-x64-ml64-exe.md).
+## Unwind Version 3 behavior
+
+> [!IMPORTANT]
+> Unwind Version 3 support is experimental and is subject to change. Enable it by using `ml64.exe /unwindv3`.
+
+In Unwind Version 3, `.SAVEXMM128` emits either a `WOD_SAVE_XMM128` or a `WOD_SAVE_XMM128_FAR` unwind code entry. Microsoft Assembler (MASM) selects the most efficient encoding based on the size of *offset*:
+
+| Unwind code | Condition |
+|---|---|
+| `WOD_SAVE_XMM128` | *offset* can be encoded as a scaled 16-bit value |
+| `WOD_SAVE_XMM128_FAR` | *offset* requires a full 32-bit value |
+
+> [!NOTE]
+> In Unwind Version 1 the directives come after the instruction. In Unwind Version 3, the directives come before the instruction.
+> `.SAVEXMM128` must appear **before** the instruction it describes. This requirement is the opposite of Version 1, where the directive follows the instruction.
+
+### Example for unwindv3
+
+```asm
+; ml64 /unwindv3 ex1.asm /link /entry:Example1 /SUBSYSTEM:CONSOLE
+_text SEGMENT
+Example1 PROC FRAME
+ .allocstack 030h
+ sub rsp, 030h
+ .savexmm128 xmm6, 0
+ movdqa [rsp], xmm6
+ .savexmm128 xmm7, 010h
+ movdqa [rsp+010h], xmm7
+.endprolog
+ ; rest of function ...
+ movdqa xmm7, [rsp+010h]
+ movdqa xmm6, [rsp]
+ add rsp, 030h
+ ret
+Example1 ENDP
+_text ENDS
+END
+```
+
+The epilogue counterpart is [.RESTOREXMM128](dot-restorexmm128.md).
## See also
+[x64 Unwind Version 3 (experimental)](directives-reference.md#x64-unwind-version-3-experimental)\
[Directives reference](directives-reference.md)\
-[MASM BNF Grammar](masm-bnf-grammar.md)
+[MASM BNF Grammar](masm-bnf-grammar.md)\
+[MASM for x64 (ml64.exe)](masm-for-x64-ml64-exe.md)
diff --git a/docs/assembler/masm/dot-setframe.md b/docs/assembler/masm/dot-setframe.md
index d33281ed97a..7eeec50f330 100644
--- a/docs/assembler/masm/dot-setframe.md
+++ b/docs/assembler/masm/dot-setframe.md
@@ -1,10 +1,10 @@
---
description: "Learn more about: .SETFRAME"
title: ".SETFRAME"
-ms.date: "12/17/2019"
+ms.date: 05/04/2026
f1_keywords: [".SETFRAME"]
helpviewer_keywords: [".SETFRAME directive"]
-ms.assetid: eaa9b5ed-4daa-4f1e-bdb6-100758007ab3
+ai-usage: ai-assisted
---
# .SETFRAME
@@ -12,13 +12,11 @@ Fills in the frame register field and offset in the unwind information using the
## Syntax
-> **.SETFRAME** *reg*, *offset*
+> `.SETFRAME` *reg*, *offset*
## Remarks
-**.SETFRAME** allows ml64.exe users to specify how a frame function unwinds, and is only allowed within the prologue, which extends from the [PROC](proc.md) FRAME declaration to the [.ENDPROLOG](dot-endprolog.md) directive. These directives do not generate code; they only generate `.xdata` and `.pdata`. **.SETFRAME** should be preceded by instructions that actually implement the actions to be unwound. It is a good practice to wrap both the unwind directives and the code they are meant to unwind in a macro to ensure agreement.
-
-For more information, see [MASM for x64 (ml64.exe)](masm-for-x64-ml64-exe.md).
+Use `.SETFRAME` to specify how a frame function unwinds. You can only use it within the prologue, which extends from the [`PROC`](proc.md) `FRAME` declaration to the [.ENDPROLOG](dot-endprolog.md) directive. These directives generate unwind metadata (`.xdata` and `.pdata` sections) but don't produce executable code. Precede `.SETFRAME` with instructions that implement the actions to be unwound. To ensure agreement, wrap both the unwind directives and the code they're meant to unwind in a macro.
## Sample
@@ -55,7 +53,51 @@ _text ENDS
END
```
+## Unwind Version 3 behavior
+
+> [!IMPORTANT]
+> Unwind Version 3 support is experimental and is subject to change. Enable it by using `ml64.exe /unwindv3`.
+
+In Unwind Version 3, `.SETFRAME` emits a `WOD_SET_FPREG` unwind code entry for the specified register using the current prologue offset. It also fills in the frame register field and offset in the unwind information. The *offset* must be a multiple of 16 and less than or equal to 240.
+
+> [!NOTE]
+> In Unwind Version 1 the directives come after the instruction. In Unwind Version 3, the directives come before the instruction.
+> `.SETFRAME` must appear **before** the instruction it describes. This requirement is the opposite of Version 1, where the directive follows the instruction.
+
+### Example for unwindv3
+
+```asm
+; ml64 /unwindv3 frmex2.asm /link /entry:frmex2 /SUBSYSTEM:CONSOLE
+_text SEGMENT
+frmex2 PROC FRAME
+ .pushreg rbp
+ push rbp
+ .allocstack 010h
+ sub rsp, 010h
+ .setframe rbp, 0
+ mov rbp, rsp
+.endprolog
+ ; modify the stack pointer outside of the prologue (similar to alloca)
+ sub rsp, 060h
+
+ ; we can unwind from the following AV because of the frame pointer
+ mov rax, 0
+ mov rax, [rax] ; AV!
+
+ add rsp, 060h
+ add rsp, 010h
+ pop rbp
+ ret
+frmex2 ENDP
+_text ENDS
+END
+```
+
+The epilogue counterpart is [.UNSETFRAME](dot-unsetframe.md).
+
## See also
+[x64 Unwind Version 3 (experimental)](directives-reference.md#x64-unwind-version-3-experimental)\
+[MASM for x64 (ml64.exe)](masm-for-x64-ml64-exe.md)\
[Directives reference](directives-reference.md)\
[MASM BNF Grammar](masm-bnf-grammar.md)
diff --git a/docs/assembler/masm/dot-unsetframe.md b/docs/assembler/masm/dot-unsetframe.md
new file mode 100644
index 00000000000..10b55371053
--- /dev/null
+++ b/docs/assembler/masm/dot-unsetframe.md
@@ -0,0 +1,82 @@
+---
+description: "Learn more about: .UNSETFRAME"
+title: ".UNSETFRAME"
+ms.date: 05/04/2026
+f1_keywords: [".UNSETFRAME"]
+helpviewer_keywords: [".UNSETFRAME directive"]
+ai-usage: ai-assisted
+---
+# .UNSETFRAME
+
+Generates a `WOD_SET_FPREG` unwind code entry for the specified register and offset using the current offset in the epilogue.
+
+## Syntax
+
+> `.UNSETFRAME` *reg*, *offset*
+
+## Parameters
+
+*reg*\
+The frame pointer register to unset.
+
+*offset*\
+The offset into the stack frame where the frame pointer was established.
+
+## Remarks
+
+> [!IMPORTANT]
+> This directive is experimental and is subject to change. Enable Unwind Version 3 with `ml64.exe /unwindv3`.
+
+`.UNSETFRAME` is only valid in Unwind Version 3. It's the epilogue counterpart to [.SETFRAME](dot-setframe.md).
+
+`.UNSETFRAME` is only allowed within an epilogue region, between [.BEGINEPILOG](dot-beginepilog.md) and [.ENDEPILOG](dot-endepilog.md). These directives generate unwind metadata (`.xdata` and `.pdata` sections) but don't produce executable code.\
+In Unwind Version 3, `.UNSETFRAME` must appear **before** the instruction that restores the stack pointer from the frame pointer register.\
+It's a good practice to wrap both the unwind directives and the code they're meant to unwind in a macro to ensure agreement.
+
+In Unwind Version 3, epilogue directives are mandatory for epilogue unwind code generation. No epilogue unwind codes are emitted without a `.BEGINEPILOG`/`.ENDEPILOG` pair.
+
+> [!NOTE]
+> In Unwind Version 1, the directive appears after the corresponding instruction. In Unwind Version 3, the directive appears **before** the instruction.
+
+## Example for unwindv3
+
+```asm
+; ml64 /unwindv3 frmex2.asm /link /entry:frmex2 /SUBSYSTEM:CONSOLE
+_text SEGMENT
+frmex2 PROC FRAME
+ .pushreg rbp
+ push rbp
+ .allocstack 010h
+ sub rsp, 010h
+ .setframe rbp, 0
+ mov rbp, rsp
+.endprolog
+ ; modify the stack pointer outside of the prologue (similar to alloca)
+ sub rsp, 060h
+
+ ; we can unwind from the following AV because of the frame pointer
+ mov rax, 0
+ mov rax, [rax] ; AV!
+
+ add rsp, 060h
+ .beginepilog
+ .unsetframe rbp, 0
+ mov rsp, rbp
+ .freestack 010h
+ add rsp, 010h
+ .popreg rbp
+ pop rbp
+ .endepilog
+ ret
+frmex2 ENDP
+_text ENDS
+END
+```
+
+## See also
+
+[x64 Unwind Version 3 (experimental)](directives-reference.md#x64-unwind-version-3-experimental)\
+[Directives Reference](directives-reference.md)\
+[.SETFRAME](dot-setframe.md)\
+[.BEGINEPILOG](dot-beginepilog.md)\
+[MASM BNF Grammar](masm-bnf-grammar.md)
diff --git a/docs/assembler/masm/masm-for-x64-ml64-exe.md b/docs/assembler/masm/masm-for-x64-ml64-exe.md
index 840b0020837..6abb9b44993 100644
--- a/docs/assembler/masm/masm-for-x64-ml64-exe.md
+++ b/docs/assembler/masm/masm-for-x64-ml64-exe.md
@@ -1,8 +1,9 @@
---
description: "Learn more about: Microsoft Macro Assembler (MASM) for x64 (ml64.exe)"
title: "MASM for x64 (ml64.exe)"
-ms.date: 09/21/2021
+ms.date: 05/07/2026
helpviewer_keywords: ["ml64", "ml64.exe", "masm for x64"]
+ai-usage: ai-assisted
---
# MASM for x64 (ml64.exe)
@@ -21,34 +22,54 @@ The Visual Studio project system supports assembler-language files built by usin
### To add an assembler-language file to an existing Visual Studio C++ project
1. Select the project in **Solution Explorer**. On the menu bar, choose **Project**, **Build Customizations**.
-
1. In the **Visual C++ Build Customization Files** dialog box, check the checkbox next to **masm(.targets,.props)**. Choose **OK** to save your selection and close the dialog box.
-
1. On the menu bar, choose **Project**, **Add New Item**.
-
1. In the **Add New Item** dialog box, select **C++ file (.cpp)** in the center pane. In the **Name** edit control, enter a new file name that has a *`.asm`* extension instead of *`.cpp`*. Choose **Add** to add the file to your project and close the dialog box.
Create your assembler-language code in the *`.asm`* file you added. When you build your solution, the MASM assembler is invoked to assemble the *`.asm`* file into an object file that is then linked into your project. To make symbol access easier, declare your assembler functions as `extern "C"` in your C++ source code, rather than using the C++ name decoration conventions in your assembler-language source files.
-## ml64-Specific Directives
+## ml64-specific directives
You can use the following ml64-specific directives in your assembler-language source code that targets x64:
- [`.ALLOCSTACK`](dot-allocstack.md)
-
- [`.ENDPROLOG`](dot-endprolog.md)
-
- [`.PUSHFRAME`](dot-pushframe.md)
-
- [`.PUSHREG`](dot-pushreg.md)
-
- [`.SAVEREG`](dot-savereg.md)
-
- [`.SAVEXMM128`](dot-savexmm128.md)
-
- [`.SETFRAME`](dot-setframe.md)
-The [`PROC`](proc.md) directive has also been updated for use with ml64.exe.
+The [`PROC`](proc.md) directive is also updated for use with ml64.exe.
+
+## Unwind Version 3 directives (experimental)
+
+> [!IMPORTANT]
+> Unwind Version 3 support is experimental and is subject to change.
+
+Unwind Version 3 is an updated unwind code scheme for x64 that generates richer stack unwind metadata. It introduces new epilogue directives, extends register support, and changes the directive ordering model.
+
+### Enable Unwind Version 3
+
+Assemble with the `/unwindv3` option: `ml64 /unwindv3 filename.asm /link /entry:FunctionName`
+
+### Key differences from Version 1
+
+| Feature | Version 1 | Version 3 |
+|---|---|---|
+| Directive ordering | Directive follows instruction | Directive precedes instruction |
+| Unwind codes | `UWOP_*` | `WOD_*` |
+| `.ALLOCSTACK` size variants | 2 (`UWOP_ALLOC_SMALL`, `UWOP_ALLOC_LARGE`) | 3 (adds `WOD_ALLOC_HUGE` for > 32 KB) |
+| `.PUSHREG` register range | R0–R15 | R0–R31 |
+| Epilogue recording | Optional | Mandatory (`.BEGINEPILOG`/`.ENDEPILOG` required) |
+| Register-pair push/pop | Not supported | `.PUSH2REG`/`.POP2REG` directives |
+
+Epilogue recording is mandatory in Version 3: `.BEGINEPILOG` and `.ENDEPILOG` must surround the epilogue instructions. Without them, no epilogue unwind codes are emitted.
+
+> [!NOTE]
+> In Unwind Version 1 the directives come after the instruction. In Unwind Version 3, the directives come before the instruction.
+
+For a complete list of Version 3 directives, see [x64 Unwind Version 3 directives](directives-reference.md) and [@UnwindVersion](at-unwindversion.md).
## 32-Bit Address Mode (Address Size Override)
diff --git a/docs/assembler/masm/ml-and-ml64-command-line-reference.md b/docs/assembler/masm/ml-and-ml64-command-line-reference.md
index e4ea469e36f..ab91d77ce37 100644
--- a/docs/assembler/masm/ml-and-ml64-command-line-reference.md
+++ b/docs/assembler/masm/ml-and-ml64-command-line-reference.md
@@ -1,9 +1,10 @@
---
title: "ML and ML64 command-line reference"
description: "Reference guide to the Microsoft MASM ML and ML64 assembler command-line options."
-ms.date: 7/3/2023
-f1_keywords: ["ML"]
-helpviewer_keywords: ["/W* MASM compiler option", "/c MASM compiler option", "/EP MASM compiler option", "/Fe MASM compiler option", "/Zp MASM compiler option", "/AT MASM compiler option", "/Zm MASM compiler option", "/Sf MASM compiler option", "/Sp MASM compiler option", "/w MASM compiler option", "/Fl MASM compiler option", "/coff MASM compiler option", "/St MASM compiler option", "/Cx MASM compiler option", "/Sl MASM compiler option", "/Cu MASM compiler option", "MASM (Microsoft Macro Assembler), ML command-line reference", "/FPi MASM compiler option", "/Zf MASM compiler option", "ML environment variable", "/Fr MASM compiler option", "/help MASM compiler option", "/Sa MASM compiler option", "/Zd MASM compiler option", "/I MASM compiler option", "/? MASM compiler option", "/Bl MASM compiler option", "/Fm MASM compiler option", "/Fo MASM compiler option", "command-line reference [ML]", "/Sn MASM compiler option", "/Gd MASM compiler option", "/D* MASM compiler option", "environment variables, ML", "/Gc MASM compiler option", "/F* MASM compiler option", "/Sc MASM compiler option", "/H MASM compiler option", "/Zs MASM compiler option", "/omf MASM compiler option", "/quiet MASM compiler option", "/Sg MASM compiler option", "/Cp MASM compiler option", "/Zi MASM compiler option", "/nologo MASM compiler option", "/Sx MASM compiler option", "/WX MASM compiler option", "/Ss MASM compiler option", "command line, reference [ML]", "/Ta MASM compiler option"]
+ms.date: 05/25/2026
+ai-usage: ai-assisted
+f1_keywords: ["ML", "/unwindv3"]
+helpviewer_keywords: ["/W* MASM compiler option", "/c MASM compiler option", "/EP MASM compiler option", "/Fe MASM compiler option", "/Zp MASM compiler option", "/AT MASM compiler option", "/Zm MASM compiler option", "/Sf MASM compiler option", "/Sp MASM compiler option", "/w MASM compiler option", "/Fl MASM compiler option", "/coff MASM compiler option", "/St MASM compiler option", "/Cx MASM compiler option", "/Sl MASM compiler option", "/Cu MASM compiler option", "MASM (Microsoft Macro Assembler), ML command-line reference", "/FPi MASM compiler option", "/Zf MASM compiler option", "ML environment variable", "/Fr MASM compiler option", "/help MASM compiler option", "/Sa MASM compiler option", "/Zd MASM compiler option", "/I MASM compiler option", "/? MASM compiler option", "/Bl MASM compiler option", "/Fm MASM compiler option", "/Fo MASM compiler option", "command-line reference [ML]", "/Sn MASM compiler option", "/Gd MASM compiler option", "/D* MASM compiler option", "environment variables, ML", "/Gc MASM compiler option", "/F* MASM compiler option", "/Sc MASM compiler option", "/H MASM compiler option", "/Zs MASM compiler option", "/omf MASM compiler option", "/quiet MASM compiler option", "/Sg MASM compiler option", "/Cp MASM compiler option", "/Zi MASM compiler option", "/nologo MASM compiler option", "/Sx MASM compiler option", "/WX MASM compiler option", "/Ss MASM compiler option", "command line, reference [ML]", "/Ta MASM compiler option", "/unwindv3 MASM compiler option"]
---
# ML and ML64 command-line reference
@@ -61,6 +62,7 @@ The options listed in the following table:
| **`/St`** *`text`* | Specifies title for source listing. Same as [`TITLE`](title.md) text. |
| **`/Sx`** | Turns on false conditionals in listing. |
| **`/Ta`** *`filename`* | Assembles source file whose name doesn't end with the *`.asm`* extension. |
+| **`/unwindv3`** | Enables experimental Unwind Version 3 unwind directive support. When specified, V3 unwind directives must appear *before* their associated instruction (the reverse of V1 behavior), epilogue recording via [`.BEGINEPILOG`](dot-beginepilog.md)/[`.ENDEPILOG`](dot-endepilog.md) is required, and the predefined macro [`@UnwindVersion`](at-unwindversion.md) returns `3`. For more information, see [MASM for x64 (ml64.exe)](masm-for-x64-ml64-exe.md).
Only available in ml64.exe. |
| **`/w`** | Same as **`/W0 /WX`**. |
| **`/W`** *`level`* | Sets the warning level, where *`level`* = 0, 1, 2, or 3. |
| **`/WX`** | If warnings are generated, returns an error code. |
@@ -69,12 +71,16 @@ The options listed in the following table:
| **`/Zf`** | Makes all symbols public. |
| **`/ZH:MD5`** | Use MD5 for checksum in debug info. |
| **`/ZH:SHA_256`** | Use SHA256 for checksum in debug info (default in Visual Studio 2022 version 17.0 and later). |
+| **`/ZH:SHA384`** | Use SHA384 for checksum in debug info.18.6.0 |
+| **`/ZH:SHA512`** | Use SHA512 for checksum in debug info.18.6.0 |
| **`/Zi`** | Generates CodeView information in object file. |
| **`/Zm`** | Enables **`M510`** option for maximum compatibility with MASM 5.1.
Not available in ml64.exe. |
| **`/Zp`**⟦*`alignment`*⟧ | Packs structures on the specified byte boundary. The *`alignment`* can be 1, 2, 4, 8, or 16. |
| **`/Zs`** | Performs a syntax check only. |
| **`/?`** | Displays a summary of ML command-line syntax and options. |
+18.6.0 This option is available starting in Visual Studio 2026 version 18.6.0 and MSVC version 14.51.
+
*`filename`*\
The name of the file.
diff --git a/docs/assembler/masm/proc.md b/docs/assembler/masm/proc.md
index 9eb65fc3770..222b437a4a9 100644
--- a/docs/assembler/masm/proc.md
+++ b/docs/assembler/masm/proc.md
@@ -12,8 +12,8 @@ Marks start and end of a procedure block called *label*. The statements in the b
## Syntax
-> *label* **PROC** ⟦*distance*⟧ ⟦*language-type*⟧ ⟦ **PUBLIC** | **PRIVATE** | **EXPORT** ⟧ ⟦__\<__*prologuearg*__>__⟧ ⟦**USES** *reglist*⟧ ⟦__,__ *parameter* ⟦__:__*tag*⟧ ...⟧\
-> ⟦**FRAME** ⟦__:__*ehandler-address*⟧ ⟧\
+> *label* `PROC` ⟦*distance*⟧ ⟦*language-type*⟧ ⟦ `PUBLIC` | `PRIVATE` | `EXPORT` ⟧ ⟦__\<__*prologuearg*__>__⟧ ⟦`USES` *reglist*⟧ ⟦__,__ *parameter* ⟦__:__*tag*⟧ ...⟧\
+> ⟦`FRAME` ⟦__:__*ehandler-address*⟧ ⟧\
> *statements*\
> *label* **ENDP**
@@ -21,9 +21,9 @@ Marks start and end of a procedure block called *label*. The statements in the b
The ⟦*distance*⟧ and ⟦*language-type*⟧ arguments are valid only in 32-bit MASM.
-⟦**FRAME** ⟦__:__*ehandler-address*⟧ ⟧ is only valid with ml64.exe, and causes MASM to generate a function table entry in .pdata and unwind information in .xdata for a function's structured exception handling unwind behavior.
+⟦`FRAME` ⟦__:__*ehandler-address*⟧ ⟧ is only valid with ml64.exe, and causes MASM to generate a function table entry in .pdata and unwind information in .xdata for a function's structured exception handling unwind behavior.
-When the **FRAME** attribute is used, it must be followed by an [.ENDPROLOG](dot-endprolog.md) directive.
+When the `FRAME` attribute is used, it must be followed by an [.ENDPROLOG](dot-endprolog.md) directive.
See [MASM for x64 (ml64.exe)](masm-for-x64-ml64-exe.md) for more information on using ml64.exe.
@@ -49,7 +49,7 @@ _text ENDS
END
```
-The above code will emit the following function table and unwind information:
+The above code emits the following function table and unwind information:
```Output
FileHeader->Machine 34404
diff --git a/docs/assembler/masm/symbols-reference.md b/docs/assembler/masm/symbols-reference.md
index c7fd4af9f81..a6c296fc5c1 100644
--- a/docs/assembler/masm/symbols-reference.md
+++ b/docs/assembler/masm/symbols-reference.md
@@ -1,9 +1,9 @@
---
description: "Learn more about: Symbols reference"
title: "Symbols reference"
-ms.date: 07/15/2020
+ms.date: 05/04/2026
helpviewer_keywords: ["MASM (Microsoft Macro Assembler), symbols reference"]
-ms.assetid: 96ed59cc-dafa-4299-bb2e-9c7c3f496491
+ai-usage: ai-assisted
---
# Symbols reference
@@ -30,6 +30,9 @@ ms.assetid: 96ed59cc-dafa-4299-bb2e-9c7c3f496491
:::column span="":::
[`@Interface`](at-interface.md)
:::column-end:::
+ :::column span="":::
+ [`@UnwindVersion`](at-unwindversion.md)
+ :::column-end:::
:::column span="":::
[`@Version`](at-version.md)
:::column-end:::
diff --git a/docs/assembler/toc.yml b/docs/assembler/toc.yml
index 8f8b923a9c3..1e90a1e19d3 100644
--- a/docs/assembler/toc.yml
+++ b/docs/assembler/toc.yml
@@ -117,6 +117,8 @@ items:
href: ../assembler/masm/dot-alpha.md
- name: ASSUME
href: ../assembler/masm/assume.md
+ - name: .BEGINEPILOG
+ href: ../assembler/masm/dot-beginepilog.md
- name: .BREAK
href: ../assembler/masm/dot-break.md
- name: BYTE
@@ -171,6 +173,8 @@ items:
href: ../assembler/masm/end-masm.md
- name: .ENDIF
href: ../assembler/masm/dot-endif.md
+ - name: .ENDEPILOG
+ href: ../assembler/masm/dot-endepilog.md
- name: ENDM
href: ../assembler/masm/endm.md
- name: ENDP
@@ -225,6 +229,8 @@ items:
href: ../assembler/masm/forc.md
- name: .FPO
href: ../assembler/masm/dot-fpo.md
+ - name: .FREESTACK
+ href: ../assembler/masm/dot-freestack.md
- name: FWORD
href: ../assembler/masm/fword.md
- name: GOTO
@@ -315,8 +321,14 @@ items:
href: ../assembler/masm/oword.md
- name: PAGE
href: ../assembler/masm/page.md
+ - name: .POP2REG
+ href: ../assembler/masm/dot-pop2reg.md
- name: POPCONTEXT
href: ../assembler/masm/popcontext.md
+ - name: .POPREG
+ href: ../assembler/masm/dot-popreg.md
+ - name: .POPFRAME
+ href: ../assembler/masm/dot-popframe.md
- name: PROC
href: ../assembler/masm/proc.md
- name: PROTO
@@ -325,6 +337,8 @@ items:
href: ../assembler/masm/public-masm.md
- name: PURGE
href: ../assembler/masm/purge.md
+ - name: .PUSH2REG
+ href: ../assembler/masm/dot-push2reg.md
- name: PUSHCONTEXT
href: ../assembler/masm/pushcontext.md
- name: .PUSHFRAME
@@ -349,6 +363,10 @@ items:
href: ../assembler/masm/repeat.md
- name: REPT
href: ../assembler/masm/rept.md
+ - name: .RESTOREREG
+ href: ../assembler/masm/dot-restorereg.md
+ - name: .RESTOREXMM128
+ href: ../assembler/masm/dot-restorexmm128.md
- name: .SAFESEH
href: ../assembler/masm/dot-safeseh.md
- name: .SALL
@@ -401,6 +419,8 @@ items:
href: ../assembler/masm/typedef-masm.md
- name: UNION
href: ../assembler/masm/union.md
+ - name: .UNSETFRAME
+ href: ../assembler/masm/dot-unsetframe.md
- name: .UNTIL
href: ../assembler/masm/dot-until.md
- name: .UNTILCXZ
@@ -479,6 +499,8 @@ items:
href: ../assembler/masm/at-substr.md
- name: "@Time"
href: ../assembler/masm/at-time.md
+ - name: "@UnwindVersion"
+ href: ../assembler/masm/at-unwindversion.md
- name: "@Version"
href: ../assembler/masm/at-version.md
- name: "@WordSize"
diff --git a/docs/build/building-on-the-command-line.md b/docs/build/building-on-the-command-line.md
index 5f7a2fdff45..ba6f8012556 100644
--- a/docs/build/building-on-the-command-line.md
+++ b/docs/build/building-on-the-command-line.md
@@ -1,202 +1,213 @@
---
title: "Use the Microsoft C++ Build Tools from the command line"
-description: "Use the Microsoft C++ (MSVC) Build Tools from the command line outside of the Visual Studio IDE."
+description: "Learn how to install and use the Microsoft C++ (MSVC) Build Tools from the command line."
ms.custom: "conceptual"
-ms.date: 04/07/2022
+ms.date: 06/02/2026
ms.topic: how-to
helpviewer_keywords: ["command-line builds [C++]", "compiling source code [C++], command line", "builds [C++], command-line", "command line [C++], building from", "command line [C++], compilers"]
+#custom intent: As a C++ developer, I want to understand the options for using the command line to compile and build my software projects.
---
# Use the Microsoft C++ Build Tools from the command line
-You can build C and C++ applications on the command line by using tools that are included in Visual Studio. The Microsoft C++ (MSVC) Build Tools are also downloadable as a standalone package. You don't need to install the Visual Studio IDE if you don't plan to use it.
+You can build C and C++ applications on the command line by using tools that are included in Visual Studio. You can also download the Microsoft C++ (MSVC) Build Tools as a standalone package. You don't need to install the Visual Studio IDE if you don't plan to use it.
> [!NOTE]
-> This article is about how to set up an environment to use the individual compilers, linkers, librarian, and other basic tools. The native project build system in Visual Studio, based on MSBuild, doesn't use the environment as described in this article. For more information on how to use MSBuild from the command line, see [MSBuild on the command line - C++](msbuild-visual-cpp.md).
+> This article is about how to set up an environment to use the individual compilers, linkers, libraries, and other basic tools. The native project build system in Visual Studio, based on MSBuild, doesn't use the environment as described in this article. For more information on how to use MSBuild from the command line, see [MSBuild on the command line - C++](msbuild-visual-cpp.md).
## Download and install the tools
::: moniker range=">=msvc-160"
-If you've installed Visual Studio and a C++ workload, you have all the command-line tools. For information on how to install C++ and Visual Studio, see [Install C++ support in Visual Studio](vscpp-step-0-installation.md). If you only want the command-line toolset, download the [Build Tools for Visual Studio](https://visualstudio.microsoft.com/downloads/). On the downloads page, expand the **Tools for Visual Studio** section to find the Build Tools download. When you run the downloaded executable, it updates and runs the Visual Studio Installer. To install only the tools you need for C++ development, select the **Desktop development with C++** workload. You can select optional libraries and toolsets to include under **Installation details**. To build code by using the Visual Studio 2015, 2017, or 2019 toolsets, select the optional MSVC v140, v141, or v142 build tools. When you're satisfied with your selections, choose **Install**.
+If you installed Visual Studio and a C++ workload, you have all the command-line tools. For information on how to install C++ and Visual Studio, see [Install C++ support in Visual Studio](vscpp-step-0-installation.md).
+
+If you want only the command-line toolset, download the [Build Tools for Visual Studio](https://visualstudio.microsoft.com/downloads/). On the downloads page, expand **Tools for Visual Studio** to find the Build Tools download. When you run the downloaded executable, it updates and runs the Visual Studio Installer.
+
+To install only the tools you need for C++ development, select the **Desktop development with C++** workload. Under **Installation details**, you can select optional libraries and toolsets. To build code by using the Visual Studio 2015, Visual Studio 2017, or Visual Studio 2019 toolsets, select the optional MSVC v140, v141, or v142 build tools. When you're satisfied with your selections, choose **Install**.
::: moniker-end
::: moniker range="<=msvc-150"
-If you've installed Visual Studio and a C++ workload, you have all the command-line tools. For information on how to install C++ and Visual Studio, see [Install C++ support in Visual Studio](vscpp-step-0-installation.md). If you only want the command-line toolset, download the [Build Tools for Visual Studio 2017](https://my.visualstudio.com/Downloads?q=2017). When you run the downloaded executable, it updates and runs the Visual Studio Installer. To install only the tools you need for C++ development, select the **Desktop development with C++** workload. You can select optional libraries and toolsets to include under **Installation details**. To build code by using the Visual Studio 2015 toolset, select the optional MSVC v140 build tools. When you're satisfied with your selections, choose **Install**.
+If you installed Visual Studio and a C++ workload, you have all the command-line tools. For information on how to install C++ and Visual Studio, see [Install C++ support in Visual Studio](vscpp-step-0-installation.md).
+
+If you want only the command-line toolset, download the [Build Tools for Visual Studio 2017](https://my.visualstudio.com/Downloads?q=2017). When you run the downloaded executable, it updates and runs the Visual Studio Installer.
+
+To install only the tools you need for C++ development, select the **Desktop development with C++** workload. Under **Installation details**, you can select optional libraries and toolsets. To build code by using the Visual Studio 2015 toolset, select the optional MSVC v140 build tools. When you're satisfied with your selections, choose **Install**.
::: moniker-end
## How to use the command-line tools
-When you choose one of the C++ workloads in the Visual Studio Installer, by default, it installs a particular version of the MSVC Build Tools package. For Visual Studio 2022 and earlier, this is organized by a *platform toolset* (v### version format) that has all the C and C++ tools for a specific version of Visual Studio. For Visual Studio 2026 and later, this consists of the MSVC version (v##.## version format), which has all the C and C++ tools for that particular MSVC package. The MSVC version is decoupled from the Visual Studio version. The tools include the C/C++ compilers, linkers, assemblers, and other build tools, and matching libraries and header files. You can use all of these tools at the command-line. They're also used internally by the Visual Studio IDE. There are separate x86-hosted and x64-hosted compilers and tools that build code for x86, x64, ARM, and ARM64 targets. Each set of tools for a particular host and target build architecture is stored in its own directory.
+When you choose one of the C++ workloads in the Visual Studio Installer, it installs a specific version of the MSVC Build Tools package by default. For Visual Studio 2022 and earlier, the package is organized by a *platform toolset* (v### version format) that includes all the C and C++ tools for a specific version of Visual Studio. Starting with Visual Studio 2026, the MSVC version is decoupled from the Visual Studio version. In other words, from Visual Studio 2026 onwards the package corresponds to the MSVC toolset version (v##.## version format), which includes all the C and C++ tools for that particular MSVC Build Tools package.
-To work correctly, the tools require several specific environment variables to be set. These variables are used to add the tools to the path, and to set the locations of include files, library files, and SDKs. To make it easy to set these environment variables, the installer creates customized *command files*, or batch files, during installation. You can run one of these command files to set a specific host and target build architecture, Windows SDK version, and platform toolset. For convenience, the installer also creates shortcuts in your Start menu. The shortcuts open developer command prompt windows by using these command files for specific combinations of host and target. These shortcuts ensure all the required environment variables are set and ready to use.
+The tools include the C/C++ compilers, linkers, assemblers, and other build tools. It includes matching libraries and header files. You can use all of these tools at the command line. The Visual Studio IDE uses them internally. There are separate x86-hosted and x64-hosted compilers and tools that build code for x86, x64, ARM, and ARM64 targets. Each set of tools for a particular host and target build architecture is stored in its own directory.
-The required environment variables are specific to your installation and to the build architecture you choose. They also might be changed by product updates or upgrades. This variability is one reason why we recommend you use an installed command prompt shortcut or command file, instead of setting the environment variables yourself.
+The tools require several environment variables to be set. These variables add the tools to the path and set the locations of include files, library files, and SDKs. To make it easy to set these environment variables, the installer creates customized *command files*, or batch files, during installation. You can run one of these command files to set a specific host and target build architecture, Windows SDK version, and platform toolset.
-The toolsets, command files, and shortcuts installed depend on your computer processor and the options you selected during installation. The x86-hosted tools and cross tools that build x86 and x64 code are always installed. If you have 64-bit Windows, the x64-hosted tools and cross tools that build x86 and x64 code are also installed. If you choose the optional C++ Universal Windows Platform tools, then the x86 and x64 tools that build ARM and ARM64 code also get installed. Other workloads may install these and other tools.
+For convenience, the installer also creates shortcuts in your **Start** menu. The shortcuts open developer Command Prompt windows by using these command files for specific combinations of host and target architectures. These shortcuts ensure all the required environment variables are set and ready to use.
-## Path and environment variables for command-line builds
+The required environment variables are specific to your installation and to the build architecture you choose. Product updates or upgrades might change the variables. This variability is one reason why we recommend you use an installed command prompt shortcut or command file, instead of setting the environment variables yourself.
-The MSVC command-line tools use the `PATH`, `TMP`, `INCLUDE`, `LIB`, and `LIBPATH` environment variables, and also use other environment variables specific to your installed tools, platforms, and SDKs. Even a simple Visual Studio installation may set twenty or more environment variables. This complexity is why we strongly recommend that you use a [developer command prompt shortcut](#developer_command_prompt_shortcuts) or one of the [customized command files](#developer_command_file_locations). We don't recommend you set these variables in the Windows environment yourself.
+The toolsets, command files, and shortcuts that the installer adds depend on your computer processor and the options you select during installation. The x86-hosted tools and cross tools that build x86 and x64 code are always installed. If you have 64-bit Windows, the x64-hosted tools and cross tools that build x86 and x64 code are also installed. If you choose the optional C++ Universal Windows Platform tools, the x86 and x64 tools that build ARM and ARM64 code are also installed. Other workloads can install these tools.
-To see which environment variables are set by a developer command prompt shortcut, you can use the `SET` command. Open a plain command prompt window and capture the output of the `SET` command for a baseline. Open a developer command prompt window and capture the output of the `SET` command for comparison. Use a diff tool such as the one built into Visual Studio to highlight the environment variables set by the developer command prompt. For more information about the compiler and linker environment variables, see [CL environment variables](reference/cl-environment-variables.md).
+## Path and environment variables for command-line builds
-## Developer command prompt shortcuts
+The MSVC command-line tools use the `PATH`, `TMP`, `INCLUDE`, `LIB`, and `LIBPATH` environment variables. They also use other environment variables specific to your installed tools, platforms, and SDKs. Even a simple Visual Studio installation can set twenty or more environment variables. This complexity is why we strongly recommend that you use a [developer command prompt shortcut](#developer_command_prompt_shortcuts) or one of the [customized command files](#developer_command_file_locations). We don't recommend you set these variables in the Windows environment yourself.
-The command prompt shortcuts are installed in a version-specific Visual Studio folder in your Windows Start menu. Here's a list of the base command prompt shortcuts and the build architectures they support:
+To see which environment variables a developer command prompt shortcut sets, use the `SET` command. Open a plain Command Prompt window and capture the output of the `SET` command for a baseline. Open a developer Command Prompt window and capture the output of the `SET` command for comparison. Use a diff tool such as the one built into Visual Studio to highlight the environment variables set by the developer command prompt. For more information about the compiler and linker environment variables, see [CL environment variables](reference/cl-environment-variables.md).
-- **Developer Command Prompt** - Sets the environment to use 32-bit, x86-native tools to build 32-bit, x86-native code.
-- **x86 Native Tools Command Prompt** - Sets the environment to use 32-bit, x86-native tools to build 32-bit, x86-native code.
-- **x64 Native Tools Command Prompt** - Sets the environment to use 64-bit, x64-native tools to build 64-bit, x64-native code.
-- **x86_x64 Cross Tools Command Prompt** - Sets the environment to use 32-bit, x86-native tools to build 64-bit, x64-native code.
-- **x64_x86 Cross Tools Command Prompt** - Sets the environment to use 64-bit, x64-native tools to build 32-bit, x86-native code.
+## Developer command prompt shortcuts
-::: moniker range=">= msvc-160"
+The command prompt shortcuts are installed in a version-specific Visual Studio folder in your Windows **Start** menu. Here's a list of the base command prompt shortcuts and the build architectures they support:
-The Start menu folder and shortcut names vary depending on the installed version of Visual Studio. If you set one, they also depend on the installation **Nickname**. For example, suppose you installed Visual Studio 2022, and you gave it a nickname of *Latest*. The developer command prompt shortcut is named **Developer Command Prompt for VS 2022 (Latest)**, in a folder named **Visual Studio 2022**.
+- **Developer Command Prompt**. Sets the environment to use 32-bit x86 tools to build 32-bit x86 code.
+- **x86 Native Tools Command Prompt**. Sets the environment to use 32-bit x86 tools to build 32-bit x86 code.
+- **x64 Native Tools Command Prompt**. Sets the environment to use 64-bit x64 tools to build 64-bit x64 code.
+- **x86_x64 Cross Tools Command Prompt**. Sets the environment to use 32-bit x86 tools to build 64-bit x64 code.
+- **x64_x86 Cross Tools Command Prompt**. Sets the environment to use 64-bit x64 tools to build 32-bit x86 code.
+::: moniker range=">=msvc-180"
+The **Start** menu folder and shortcut names vary depending on the installed version of Visual Studio. For example, suppose you installed the Visual Studio 2026 Insiders version. The developer command prompt shortcut is named **Developer Command Prompt for VS Insiders** in **Start** > **Programs** > **Visual Studio** > **Visual Studio Tools**.
+::: moniker-end
+::: moniker range="msvc-170"
+The **Start** menu folder and shortcut names vary depending on the installed version of Visual Studio. For example, the developer prompt shortcut for Visual Studio 2022 is named **Developer Command Prompt for VS 2022** in **Start** > **Programs** > **Visual Studio 2022** > **Visual Studio Tools**.
+::: moniker-end
+::: moniker range="msvc-160"
+The **Start** menu folder and shortcut names vary depending on the installed version of Visual Studio. For example, the developer prompt shortcut for Visual Studio 2019 is named **Developer Command Prompt for VS 2019** in **Start** > **Programs** > **Visual Studio 2019** > **Visual Studio Tools**.
::: moniker-end
::: moniker range="msvc-150"
-
-The Start menu folder and shortcut names vary depending on the installed version of Visual Studio. If you set one, they also depend on the installation **Nickname**. For example, suppose you installed Visual Studio 2017, and you gave it a nickname of *Latest*. The developer command prompt shortcut is named **Developer Command Prompt for VS 2017 (Latest)**, in a folder named **Visual Studio 2017**.
-
+The **Start** menu folder and shortcut names vary depending on the installed version of Visual Studio. For example, the developer prompt shortcut for Visual Studio 2017 is named **Developer Command Prompt for VS 2017** in **Start** > **Programs** > **Visual Studio 2017** > **Visual Studio Tools**.
::: moniker-end
::: moniker range="< msvc-150"
-
-The Start menu folder and shortcut names vary depending on the installed version of Visual Studio. For example, suppose you installed Visual Studio 2015. The developer command prompt shortcut is named **Developer Command Prompt for VS 2015**.
-
+The **Start** menu folder and shortcut names vary depending on the installed version of Visual Studio. For example, the developer prompt shortcut for Visual Studio 2015 is named **Developer Command Prompt for VS 2015** in **Start** > **Programs** > **Visual Studio 2015** > **Visual Studio Tools**.
::: moniker-end
> [!NOTE]
-> Several command-line tools or tool options may require Administrator permission. If you have permission issues when you use them, we recommend that you open the developer command prompt window by using the **Run as Administrator** option. Right-click to open the shortcut menu for the command prompt window, then choose **More**, **Run as administrator**.
+> Several command-line tools or tool options require Administrator privileges. If you have permission issues when you use them, we recommend that you open the developer Command Prompt window by using the **Run as Administrator** option. Right-click to open the shortcut menu for the Command Prompt window, then choose **More** > **Run as administrator**.
-### To open a developer command prompt window
+### To open a developer Command Prompt window
-1. On the desktop, open the Windows **Start** menu. In Windows 11, choose the **All apps** button to open the list of installed apps. In Windows 10, the list is open to the left. Scroll down the list to find and open the folder (not the app) for your version of Visual Studio, for example, **Visual Studio 2022**.
-
-1. In the folder, choose the **Developer Command Prompt** for your version of Visual Studio. This shortcut starts a developer command prompt window that uses the default build architecture of 32-bit, x86-native tools to build 32-bit, x86-native code. If you prefer a non-default build architecture, choose one of the native or cross tools command prompts to specify the host and target architecture.
+1. On the desktop, open the Windows **Start** menu. In Windows 11, choose **All apps** to open the list of installed apps. In Windows 10, the list is open to the left. Scroll down the list to find and open the folder (not the app) for your version of Visual Studio, such as **Visual Studio 2022** or **Visual Studio** for version 2026 and later.
+1. In the folder, choose the **Developer Command Prompt** for your version of Visual Studio. This shortcut starts a developer Command Prompt window that sets the environment to use 32-bit x86 tools to build 32-bit x86 code. If you prefer a nondefault build architecture, choose one of the native or cross tools command prompts to specify the host and target architecture.
For an even faster way to open a developer command prompt, enter *developer command prompt* in the desktop search box. Then choose the result you want.
> [!NOTE]
-> By default, the current working directory in a developer command prompt is the root of your Visual Studio installation in the Program Files directory. This isn't an appropriate location for your code and projects. Change the current working directory to another location before you create a project. The IDE creates projects in your user directory, typically in *`%USERPROFILE%\source\repos`*.
+> By default, the current working directory in a developer command prompt is the root of your Visual Studio installation in the Program Files directory. This location isn't appropriate for your code and projects. Change the current working directory to another location before you create a project. The IDE creates projects in your user directory, typically in `%USERPROFILE%\source\repos`.
## Developer command file locations
-If you prefer to set the build environment in an existing command prompt window, you can use one of the command files created by the installer. We recommend you set the environment in a new command prompt window. We don't recommend you later switch environments in the same command window.
+If you prefer to set the build environment in an existing Command Prompt window, you can use one of the command files created by the installer. We recommend you set the environment in a new Command Prompt window. We don't recommend you later switch environments in the same command window.
+
+::: moniker range=">= msvc-180"
-::: moniker range=">= msvc-170"
+The command file location depends on the version of Visual Studio you installed, and on choices you made during installation. For Visual Studio 2026 and later, the typical installation location on a 64-bit system is `C:\Program Files\Microsoft Visual Studio\18\`. The `` can be `Insiders`, `Community`, `Professional`, `Enterprise`, `BuildTools`.
-The command file location depends on the version of Visual Studio you installed, and on choices you made during installation. For Visual Studio 2022, the typical installation location on a 64-bit system is in *`\Program Files\Microsoft Visual Studio\2022\`*. The *``* may be Community, Professional, Enterprise, BuildTools, or another nickname you supplied.
+::: moniker-end
+::: moniker range="= msvc-170"
+
+The command file location depends on the version of Visual Studio you installed, and on choices you made during installation. For Visual Studio 2022, the typical installation location is `C:\Program Files\Microsoft Visual Studio\2022\`. The `` can be `Community`, `Professional`, `Enterprise`, `BuildTools`.
::: moniker-end
::: moniker range="= msvc-160"
-The command file location depends on the version of Visual Studio you installed, and on choices you made during installation. For Visual Studio 2019, the typical installation location on a 64-bit system is in *`\Program Files (x86)\Microsoft Visual Studio\2019\`*. The *``* may be Community, Professional, Enterprise, BuildTools, or another nickname you supplied.
+The command file location depends on the version of Visual Studio you installed, and on choices you made during installation. For Visual Studio 2019, the typical installation location on a 64-bit system is `C:\Program Files (x86)\Microsoft Visual Studio\2019\`. The `` can be `Community`, `Professional`, `Enterprise`, `BuildTools`.
::: moniker-end
::: moniker range="= msvc-150"
-The command file location depends on the version of Visual Studio you installed, and on choices you made during installation. For Visual Studio 2017, the typical installation location on a 64-bit system is in *`\Program Files (x86)\Microsoft Visual Studio\2017\`*. The *``* may be Community, Professional, Enterprise, BuildTools, or another nickname you supplied.
+The command file location depends on the version of Visual Studio you installed, and on choices you made during installation. For Visual Studio 2017, the typical installation location on a 64-bit system is `C:\Program Files (x86)\Microsoft Visual Studio\2017\`. The `` can be `Community`, `Professional`, `Enterprise`, `BuildTools`.
::: moniker-end
::: moniker range="< msvc-150"
-The command file location depends on the Visual Studio version, and the installation directory. For Visual Studio 2015, the typical installation location on a 64-bit system is in *`\Program Files (x86)\Microsoft Visual Studio 14.0`*.
+The command file location depends on the Visual Studio version, and the installation directory. For Visual Studio 2015, the typical installation location on a 64-bit system is `C:\Program Files (x86)\Microsoft Visual Studio 14.0`.
::: moniker-end
-The primary developer command prompt command file, *`VsDevCmd.bat`*, is located in the *`Common7\Tools`* subdirectory. When no parameters are specified, it sets the environment to use the x86-native tools to build 32-bit x86 code.
+The primary developer command prompt command file, `VsDevCmd.bat`, is located in the `Common7\Tools` directory. When you don't specify parameters, it sets the environment to use the x86-native tools to build 32-bit x86 code.
::: moniker range=">= msvc-150"
-More command files are available to set up specific build architectures. The command files available depend on the Visual Studio workloads and options you've installed. In Visual Studio 2017 and Visual Studio 2019, you'll find them in the *`VC\Auxiliary\Build`* subdirectory.
+More command files are available to set up specific build architectures. The command files available depend on the Visual Studio workloads and options you installed. In Visual Studio 2017 and Visual Studio 2019, you find them in the `VC\Auxiliary\Build` directory.
::: moniker-end
::: moniker range="< msvc-150"
-More command files are available to set up specific build architectures. The command files available depend on the Visual Studio workloads and options you've installed. In Visual Studio 2015, they're located in the *`VC`*, *`VC\bin`*, or *`VC\bin\`* subdirectories, where *``* is one of the native or cross-compiler options.
+More command files are available to set up specific build architectures. The command files available depend on the Visual Studio workloads and options you installed. In Visual Studio 2015, they're located in the `VC`, `VC\bin`, or `VC\bin\` directories, where `` is one of the native or cross-compiler options.
::: moniker-end
-These command files set default parameters and call *`VsDevCmd.bat`* to set up the specified build architecture environment. A typical installation may include these command files:
+These command files set default parameters and call `VsDevCmd.bat` to set up the specified build architecture environment. A typical installation might include these command files:
| Command File | Host and Target architectures |
|--|--|
-| *`vcvars32.bat`* | Use the 32-bit x86-native tools to build 32-bit x86 code. |
-| *`vcvars64.bat`* | Use the 64-bit x64-native tools to build 64-bit x64 code. |
-| *`vcvarsx86_amd64.bat`* | Use the 32-bit x86-native cross tools to build 64-bit x64 code. |
-| *`vcvarsamd64_x86.bat`* | Use the 64-bit x64-native cross tools to build 32-bit x86 code. |
-| *`vcvarsx86_arm.bat`* | Use the 32-bit x86-native cross tools to build ARM code. |
-| *`vcvarsamd64_arm.bat`* | Use the 64-bit x64-native cross tools to build ARM code. |
-| *`vcvarsx86_arm64.bat`* | Use the 32-bit x86-native cross tools to build ARM64 code. |
-| *`vcvarsamd64_arm64.bat`* | Use the 64-bit x64-native cross tools to build ARM64 code. |
-| *`vcvarsall.bat`* | Use parameters to specify the host and target architectures, Windows SDK, and platform choices. For a list of supported options, call by using a `/help` parameter. |
+| `vcvars32.bat` | Use the 32-bit x86-native tools to build 32-bit x86 code. |
+| `vcvars64.bat` | Use the 64-bit x64-native tools to build 64-bit x64 code. |
+| `vcvarsx86_amd64.bat` | Use the 32-bit x86-native cross tools to build 64-bit x64 code. |
+| `vcvarsamd64_x86.bat` | Use the 64-bit x64-native cross tools to build 32-bit x86 code. |
+| `vcvarsx86_arm.bat` | Use the 32-bit x86-native cross tools to build ARM code. |
+| `vcvarsamd64_arm.bat` | Use the 64-bit x64-native cross tools to build ARM code. |
+| `vcvarsx86_arm64.bat` | Use the 32-bit x86-native cross tools to build ARM64 code. |
+| `vcvarsamd64_arm64.bat` | Use the 64-bit x64-native cross tools to build ARM64 code. |
+| `vcvarsall.bat` | Use parameters to specify the host and target architectures, Windows SDK, and platform choices. For a list of supported options, call by using a `/help` parameter. |
> [!CAUTION]
-> The *`vcvarsall.bat`* file and other Visual Studio command files can vary from computer to computer. Do not replace a missing or damaged *`vcvarsall.bat`* file by using a file from another computer. Rerun the Visual Studio installer to replace the missing file.
+> The `vcvarsall.bat` file and other Visual Studio command files can vary from computer to computer. Don't replace a missing or damaged `vcvarsall.bat` file by using a file from another computer. Rerun the Visual Studio installer to replace the missing file.
>
-> The *`vcvarsall.bat`* file also varies from version to version. If the current version of Visual Studio is installed on a computer that also has an earlier version of Visual Studio, do not run *`vcvarsall.bat`* or another Visual Studio command file from different versions in the same command prompt window.
+> The `vcvarsall.bat` file also varies from version to version. If the current version of Visual Studio is installed on a computer that also has an earlier version of Visual Studio, don't run `vcvarsall.bat` or another Visual Studio command file from different versions in the same Command Prompt window.
## Use the developer tools in an existing command window
-The simplest way to specify a particular build architecture in an existing command window is to use the *`vcvarsall.bat`* file. Use *`vcvarsall.bat`* to set environment variables to configure the command line for native 32-bit or 64-bit compilation. Arguments let you specify cross-compilation to x86, x64, ARM, or ARM64 processors. You can target Microsoft Store, Universal Windows Platform, or Windows Desktop platforms. You can even specify which Windows SDK to use, and select the platform toolset version.
+The simplest way to specify a particular build architecture in an existing command window is to use the `vcvarsall.bat` file. Use `vcvarsall.bat` to set environment variables to configure the Command Prompt window for native 32-bit or 64-bit compilation. Arguments let you specify cross-compilation to x86, x64, ARM, or ARM64 processors. You can target Microsoft Store, Universal Windows Platform, or Windows Desktop platforms. You can even specify which Windows SDK to use, and select the platform toolset version.
-When used with no arguments, *`vcvarsall.bat`* configures the environment variables to use the current x86-native compiler for 32-bit Windows Desktop targets. You can add arguments to configure the environment to use any of the native or cross compiler tools. *`vcvarsall.bat`* displays an error message if you specify a configuration that's not installed, or not available on your computer.
+When you use `vcvarsall.bat` with no arguments, it configures the environment variables to use the current x86-native compiler for 32-bit Windows Desktop targets. Add arguments to configure the environment to use any of the native or cross compiler tools. `vcvarsall.bat` displays an error message if you specify a configuration that isn't installed, or isn't available on your computer.
### `vcvarsall` syntax
-> **`vcvarsall.bat`** [*`architecture`*] [*`platform_type`*] [*`winsdk_version`*] [**`-vcvars_ver=`***`vcversion`*] [*`spectre_mode`*]
-
-*`architecture`*\
-This optional argument specifies the host and target architecture to use. If *`architecture`* isn't specified, the default build environment is used. These arguments are supported:
-
-| *`architecture`* | Compiler | Host computer architecture | Build output (target) architecture |
-|--|--|--|--|
-| `x86` | x86 32-bit native | x86, x64 | x86 |
-| `x86_amd64` or `x86_x64` | x64 on x86 cross | x86, x64 | x64 |
-| `x86_arm` | ARM on x86 cross | x86, x64 | ARM |
-| `x86_arm64` | ARM64 on x86 cross | x86, x64 | ARM64 |
-| `amd64` or `x64` | x64 64-bit native | x64 | x64 |
-| `amd64_x86` or `x64_x86` | x86 on x64 cross | x64 | x86 |
-| `amd64_arm` or `x64_arm` | ARM on x64 cross | x64 | ARM |
-| `amd64_arm64` or `x64_arm64` | ARM64 on x64 cross | x64 | ARM64 |
+`vcvarsall.bat` [`architecture`] [`platform_type`] [`winsdk_version`] [`-vcvars_ver=`*`vcversion`*] [`spectre_mode`]
-*`platform_type`*\
-This optional argument allows you to specify **`store`** or **`uwp`** as the platform type. By default, the environment is set to build desktop or console apps.
+- `architecture`
-*`winsdk_version`*\
-Optionally specifies the version of the Windows SDK to use. By default, the latest installed Windows SDK is used. To specify the Windows SDK version, you can use a full Windows SDK number such as **`10.0.10240.0`**, or specify **`8.1`** to use the Windows 8.1 SDK.
+ This optional argument specifies the host and target architecture to use. If you don't specify `architecture`, the default build environment is used. The following arguments are supported:
-*`vcversion`*\
-Optionally specifies the Visual Studio compiler toolset to use. By default, the environment is set to use the current Visual Studio compiler toolset.
+ | `architecture` | Compiler | Host computer architecture | Build output (target) architecture |
+ |--|--|--|--|
+ | `x86` | x86 32-bit native | x86, x64 | x86 |
+ | `x86_amd64` or `x86_x64` | x64 on x86 cross | x86, x64 | x64 |
+ | `x86_arm` | ARM on x86 cross | x86, x64 | ARM |
+ | `x86_arm64` | ARM64 on x86 cross | x86, x64 | ARM64 |
+ | `amd64` or `x64` | x64 64-bit native | x64 | x64 |
+ | `amd64_x86` or `x64_x86` | x86 on x64 cross | x64 | x86 |
+ | `amd64_arm` or `x64_arm` | ARM on x64 cross | x64 | ARM |
+ | `amd64_arm64` or `x64_arm64` | ARM64 on x64 cross | x64 | ARM64 |
-::: moniker range=">= msvc-160"
+- `platform_type`
-Use **-vcvars_ver=14.2x.yyyyy** to specify a specific version of the Visual Studio 2019 compiler toolset.
+ This optional argument specifies `store` or `uwp` as the platform type. By default, the environment is set to build desktop or console apps.
-Use **-vcvars_ver=14.29** to specify the latest version of the Visual Studio 2019 compiler toolset.
+- `winsdk_version`
-::: moniker-end
-::: moniker range="= msvc-150"
+ Optionally specifies the version of the Windows SDK to use. By default, the latest installed Windows SDK is used. To specify the Windows SDK version, use a full Windows SDK number such as `10.0.10240.0`, or specify `8.1` to use the Windows 8.1 SDK.
-Use **-vcvars_ver=14.16** to specify the latest version of the Visual Studio 2017 compiler toolset.
+- `vcversion`
-Use **-vcvars_ver=14.1x.yyyyy** to specify a specific version of the Visual Studio 2017 compiler toolset.
-
-::: moniker-end
+ Optionally specifies the Visual Studio compiler toolset to use. By default, the environment uses the latest installed Visual Studio compiler toolset. The following table shows example `vcvars_ver` values:
-Use **-vcvars_ver=14.0** to specify the Visual Studio 2015 compiler toolset.
+ | `vcvars_ver={value}` | Result | VS 2026 example | VS 2022 example | VS 2019 example | VS 2017 example |
+ |--|--|--|--|--|--|
+ | `"Preview"` | Use the Visual Studio preview compiler toolset. | Supported | Not supported | Not supported | Not supported |
+ | `"14.0"` | Use the Visual Studio 2015 compiler toolset. | Supported | Supported | Supported | Supported |
+ | `"14.xx"` | Use the latest installed `14.xx.yyyyy` toolset. | `"14.51"` | `"14.44"` | `"14.29"` | `"14.16"` |
+ | `"14.xx.yyyyy"` | Use a specific full version number. | `"14.51.36231"` | `"14.44.35207"` | `"14.29.30133"` | `"14.16.27034"` |
-*`spectre_mode`*\
-Leave this parameter out to use libraries without Spectre mitigations. Use the value **`spectre`** to use libraries with Spectre mitigations.
+- `spectre_mode`
-#### To set up the build environment in an existing command prompt window
+ Leave this parameter out to use libraries without Spectre mitigations. Specify `spectre` to use libraries with Spectre mitigations.
-1. At the command prompt, use the `CD` command to change to the Visual Studio installation directory. Then, use `CD` again to change to the subdirectory that contains the configuration-specific command files. For Visual Studio 2019 and Visual Studio 2017, use the *`VC\Auxiliary\Build`* subdirectory. For Visual Studio 2015, use the *`VC`* subdirectory.
+#### To set up the build environment in an existing Command Prompt window
-1. Enter the command for your preferred developer environment. For example, to build ARM code for UWP on a 64-bit platform, using the latest Windows SDK and Visual Studio compiler toolset, use this command line:
+1. At the command prompt, use the `CD` command to change to the Visual Studio installation directory. For example, `C:\Program Files\Microsoft Visual Studio\18\Professional` if you are using Visual studio 2026. Then, use `CD` again to change to the subdirectory that contains the configuration-specific command files. For Visual Studio 2017 and beyond, use the `VC\Auxiliary\Build` subdirectory. For Visual Studio 2015, use the `VC` subdirectory.
+1. Enter the command for your preferred developer environment. For example, to build ARM code for UWP on a 64-bit platform, using the latest Windows SDK and Visual Studio compiler toolset, use this command:
```cmd
vcvarsall.bat amd64_arm uwp
@@ -204,37 +215,73 @@ Leave this parameter out to use libraries without Spectre mitigations. Use the v
## Create your own command prompt shortcut
-::: moniker range=">= msvc-160"
+::: moniker range=">=msvc-180"
-Open the Properties dialog for a developer command prompt shortcut to see the command target used. For example, the target for the **x64 Native Tools Command Prompt for VS 2019** shortcut is something similar to:
+Open the **Properties** dialog for a developer command prompt shortcut to see the command target used. For example, the target for the **x64 Native Tools Command Prompt for VS** shortcut is similar to:
```cmd
-%comspec% /k "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat"
+%comspec% /k "C:\Program Files\Microsoft Visual Studio\18\Professional\VC\Auxiliary\Build\vcvars64.bat"
+```
+
+:::moniker-end
+::: moniker range="=msvc-170"
+
+Open the **Properties** dialog for a developer command prompt shortcut to see the command target used. For example, the target for the **Developer Command Prompt for VS 2022** shortcut is similar to:
+
+```cmd
+%comspec% /k "C:\Program Files\Microsoft Visual Studio\2022\Professional\Common7\Tools\VsDevCmd.bat"
+```
+
+:::moniker-end
+::: moniker range="= msvc-160"
+
+Open the **Properties** dialog for a developer command prompt shortcut to see the command target used. For example, the target for the **Developer Command Prompt for VS 2019** shortcut is similar to:
+
+```cmd
+%comspec% /k "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\Common7\Tools\VsDevCmd.bat"
```
::: moniker-end
::: moniker range="= msvc-150"
-Open the Properties dialog for a developer command prompt shortcut to see the command target used. For example, the target for the **x64 Native Tools Command Prompt for VS 2017** shortcut is something similar to:
+Open the **Properties** dialog for a developer command prompt shortcut to see the command target used. For example, the target for the **Developer Command Prompt for VS 2017** shortcut is similar to:
```cmd
-%comspec% /k "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat"
+%comspec% /k "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\Tools\VsDevCmd.bat"
```
::: moniker-end
::: moniker range="< msvc-150"
-Open the Properties dialog for a developer command prompt shortcut to see the command target used. For example, the target for the **VS2015 x64 Native Tools Command Prompt** shortcut is something similar to:
+Open the **Properties** dialog for a developer command prompt shortcut to see the command target used. For example, the target for the **Developer Command Prompt for VS2015** shortcut is similar to:
+
+```cmd
+%comspec% /k "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools\VsDevCmd.bat"
+```
+
+::: moniker-end
+
+The architecture-specific batch files set the `architecture` parameter and call `vcvarsall.bat`. You can pass the same options to these batch files as you pass to `vcvarsall.bat`, or you can just call `vcvarsall.bat` directly. To specify parameters for your own command shortcut, add them to the end of the command in double quotes. To use an earlier compiler toolset, specify the version number.
+
+You can only target ARM64 starting with Visual Studio 2026 because ARM32 targeting was removed then.
+
+Here's a shortcut to build ARM64 code for UWP on a 64-bit platform, using the latest Windows SDK. Targeting ARM64 is shown for Visual Studio 2026 and later. Targeting ARM32 is shown for earlier versions.
+
+::: moniker range=">= msvc-180"
```cmd
-%comspec% /k "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" amd64
+%comspec% /k "C:\Program Files\Microsoft Visual Studio\18\Professional\VC\Auxiliary\Build\vcvarsall.bat" amd64_arm64 uwp -vcvars_ver=14.50
```
::: moniker-end
+::: moniker range="= msvc-170"
-The architecture-specific batch files set the *`architecture`* parameter and call *`vcvarsall.bat`*. You can pass the same options to these batch files as you would pass to *`vcvarsall.bat`*, or you can just call *`vcvarsall.bat`* directly. To specify parameters for your own command shortcut, add them to the end of the command in double-quotes. For example, here's a shortcut to build ARM code for UWP on a 64-bit platform, using the latest Windows SDK. To use an earlier compiler toolset, specify the version number. Use something like this command target in your shortcut:
+```cmd
+%comspec% /k "C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Auxiliary\Build\vcvarsall.bat" amd64_arm uwp -vcvars_ver=14.44
+```
-::: moniker range=">= msvc-160"
+::: moniker-end
+::: moniker range="= msvc-160"
```cmd
%comspec% /k "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" amd64_arm uwp -vcvars_ver=14.29
@@ -256,17 +303,19 @@ The architecture-specific batch files set the *`architecture`* parameter and cal
::: moniker-end
-Adjust the path to reflect your Visual Studio installation directory. The *`vcvarsall.bat`* file has additional information about specific version numbers.
+Adjust the path to reflect your Visual Studio installation directory. The `vcvarsall.bat` file has more information about specific version numbers.
## Command-line tools
To build a C/C++ project at a command prompt, Visual Studio provides these command-line tools:
-[`CL`](reference/compiling-a-c-cpp-program.md)\
-Use the compiler (`cl.exe`) to compile and link source code files into apps, libraries, and DLLs.
+- [CL](reference/compiling-a-c-cpp-program.md)
-[`Link`](reference/linking.md)\
-Use the linker (`link.exe`) to link compiled object files and libraries into apps and DLLs.
+ Use the compiler (`cl.exe`) to compile and link source code files into apps, libraries, and DLLs.
+
+- [Link](reference/linking.md)
+
+ Use the linker (`link.exe`) to link compiled object files and libraries into apps and DLLs.
When you build on the command line, the F1 command isn't available for instant help. Instead, you can use a search engine to get information about warnings, errors, and messages. You can also download and use the offline help files. To use the search in Microsoft Learn, enter your query in the search box at the top of any article.
@@ -274,57 +323,33 @@ When you build on the command line, the F1 command isn't available for instant h
By default, the Visual Studio IDE uses native project build systems based on MSBuild. You can invoke MSBuild directly to build projects without using the IDE. You can also use the `devenv` command to use Visual Studio to build projects and solutions. Visual Studio also supports build systems based on CMake or NMake.
-[`MSBuild`](msbuild-visual-cpp.md)\
-Use MSBuild (`msbuild.exe`) and a project file (`.vcxproj`) to configure a build and invoke the toolset without loading the Visual Studio IDE. It's equivalent to running the **Build** project or **Build Solution** command in the Visual Studio IDE. MSBuild has advantages over the IDE when you build at the command line. You don't have to install the full IDE on all your build servers and build pipelines. You avoid the extra overhead of the IDE. MSBuild runs in containerized build environments, and supports a [binary logger](https://msbuildlog.com/).
-
-[`DEVENV`](/visualstudio/ide/reference/devenv-command-line-switches)\
-Use DEVENV (`devenv.exe`) combined with a command-line switch such as **`/Build`** or **`/Clean`** to execute certain build commands without displaying the Visual Studio IDE.
-
-[`CMake`](../build/cmake-projects-in-visual-studio.md)\
-CMake (`cmake.exe`) is a cross-platform, open-source tool for defining build processes that run on multiple platforms. CMake can configure and control native build tools for its supported platforms, such as MSBuild and Make. For more information about CMake, see the [CMake documentation](https://cmake.org/cmake/help/latest/index.html#).
-
-[`NMAKE`](reference/nmake-reference.md)\
-Use NMAKE (`nmake.exe`) to build C++ projects by using a traditional makefile.
-
-> [!NOTE]
-> Starting in Visual Studio 2019 version 16.5, MSBuild and DEVENV don't use the command-line environment to control the toolset and libraries used.
+- [MSBuild](msbuild-visual-cpp.md)
-## In this section
+ Use MSBuild (`msbuild.exe`) and a project file (`.vcxproj`) to configure a build and invoke the toolset without loading the Visual Studio IDE. It's equivalent to running the **Build** project or **Build Solution** command in the Visual Studio IDE. MSBuild has advantages over the IDE when you build at the command line. You don't have to install the full IDE on all your build servers and build pipelines. You avoid the extra overhead of the IDE. MSBuild runs in containerized build environments, and supports a [binary logger](https://msbuildlog.com/).
-These articles show how to build apps on the command line, and describe how to customize the command-line build environment. Some show how to use 64-bit toolsets, and target x86, x64, ARM, and ARM64 platforms. They also describe use of the command-line build tools MSBuild and NMAKE.
+- [DEVENV](/visualstudio/ide/reference/devenv-command-line-switches)
-[Walkthrough: Compiling a native C++ program on the command line](walkthrough-compiling-a-native-cpp-program-on-the-command-line.md)\
-Gives an example that shows how to create and compile a C++ program on the command line.
+ Use DEVENV (`devenv.exe`) combined with a command-line switch such as `/Build` or `/Clean` to execute certain build commands without displaying the Visual Studio IDE.
-[Walkthrough: Compile a C program on the command line](walkthrough-compile-a-c-program-on-the-command-line.md)\
-Describes how to compile a program written in the C programming language.
+- [CMake](../build/cmake-projects-in-visual-studio.md)
-[Walkthrough: Compiling a C++/CLI program on the command line](walkthrough-compiling-a-cpp-cli-program-on-the-command-line.md)\
-Describes how to create and compile a C++/CLI program that uses the .NET Framework.
+ CMake (`cmake.exe`) is a cross-platform open-source tool for defining build processes that run on multiple platforms. CMake can configure and control native build tools for its supported platforms, such as MSBuild and Make. For more information about CMake, see the [CMake documentation](https://cmake.org/cmake/help/latest/index.html#).
-[Walkthrough: Compiling a C++/CX program on the command line](walkthrough-compiling-a-cpp-cx-program-on-the-command-line.md)\
-Describes how to create and compile a C++/CX program that uses the Windows Runtime.
+- [NMAKE](reference/nmake-reference.md)
-[NMAKE reference](reference/nmake-reference.md)\
-Provides links to articles that describe the Microsoft Program Maintenance Utility (`NMAKE.EXE`).
+ Use NMAKE (`nmake.exe`) to build C++ projects by using a traditional makefile.
-[MSBuild on the command line - C++](msbuild-visual-cpp.md)\
-Provides links to articles that discuss how to use `msbuild.exe` from the command line.
-
-## Related sections
-
-[`/MD`, `/MT`, `/LD` (Use run-time library)](reference/md-mt-ld-use-run-time-library.md)\
-Describes how to use these compiler options to use a Debug or Release run-time library.
-
-[C/C++ compiler options](reference/compiler-options.md)\
-Provides links to articles that discuss the C and C++ compiler options and `CL.exe`.
-
-[MSVC linker options](reference/linker-options.md)\
-Provides links to articles that discuss the linker options and `LINK.exe`.
-
-[Additional MSVC build tools](reference/c-cpp-build-tools.md)\
-Provides links to the C/C++ build tools that are included in Visual Studio.
+> [!NOTE]
+> Starting in Visual Studio 2019 version 16.5, MSBuild and DEVENV don't use the command-line environment to control the toolset and libraries used.
## See also
-[Projects and build systems](projects-and-build-systems-cpp.md)
+- [Walkthrough: Compiling a native C++ program on the command line](walkthrough-compiling-a-native-cpp-program-on-the-command-line.md)
+- [Walkthrough: Compile a C program on the command line](walkthrough-compile-a-c-program-on-the-command-line.md)
+- [Walkthrough: Compiling a C++/CLI program on the command line](walkthrough-compiling-a-cpp-cli-program-on-the-command-line.md)
+- [Walkthrough: Compiling a C++/CX program on the command line](walkthrough-compiling-a-cpp-cx-program-on-the-command-line.md)
+- [Projects and build systems](projects-and-build-systems-cpp.md)
+- [`/MD`, `/MT`, `/LD` (Use run-time library)](reference/md-mt-ld-use-run-time-library.md)
+- [C/C++ compiler options](reference/compiler-options.md)
+- [MSVC linker options](reference/linker-options.md)
+- [Additional MSVC build tools](reference/c-cpp-build-tools.md)
diff --git a/docs/build/cmake-presets-vs.md b/docs/build/cmake-presets-vs.md
index 5282a491801..62d80010a54 100644
--- a/docs/build/cmake-presets-vs.md
+++ b/docs/build/cmake-presets-vs.md
@@ -4,6 +4,7 @@ description: "Reference for using CMake Presets to configure and build CMake pro
ms.date: 06/09/2023
ms.topic: reference
ms.custom: sfi-image-nochange
+ai-usage: ai-assisted
---
# Configure and build with CMake Presets in Visual Studio
@@ -460,6 +461,38 @@ The `` part lists other compilation flags, like `"-fno-omit-
Pass runtime flags to AddressSanitizer by using the `ASAN_OPTIONS` field in *`launch.vs.json`*. `ASAN_OPTIONS` defaults to `detect_leaks=0` when no other runtime options are specified because LeakSanitizer isn't supported in Visual Studio.
+## Enable Segment Heap
+
+The Segment Heap is a Windows heap implementation that reduces memory usage and fragmentation. Visual Studio ships a CMake script that enables Segment Heap for your project by adding the required manifest settings. New C++ CMake projects enable Segment Heap by default.
+
+To enable Segment Heap, set `CMAKE_PROJECT_TOP_LEVEL_INCLUDES` in the `cacheVariables` map of your Configure Preset in *`CMakePresets.json`*. Optionally, set the `VS_SEGMENT_HEAP_ALLOWLIST` and `VS_SEGMENT_HEAP_EXCLUDE` environment variables to control which targets in the project use Segment Heap. Separate target names with semicolons:
+
+ ```json
+{
+ "configurePresets": [
+ {
+ // ...
+ "environment": {
+ "VS_SEGMENT_HEAP_ALLOWLIST": "target1;target2;",
+ "VS_SEGMENT_HEAP_EXCLUDE": "target3;"
+ },
+ "cacheVariables": {
+ "CMAKE_PROJECT_TOP_LEVEL_INCLUDES": "$env{VSINSTALLDIR}Common7/IDE/CommonExtensions/Microsoft/CMake/cmake/Microsoft/SegmentHeap.cmake"
+ }
+ }
+ ]
+}
+
+```
+
+> [!NOTE]
+> `CMAKE_PROJECT_TOP_LEVEL_INCLUDES` is available in CMake 3.24 or later.
+
+- `VS_SEGMENT_HEAP_ALLOWLIST` — Apply the Segment Heap manifest entry only to the listed targets. Exclude all other targets.
+- `VS_SEGMENT_HEAP_EXCLUDE` — Exclude the listed targets from using the Segment Heap.
+
+In this example, `CMAKE_PROJECT_TOP_LEVEL_INCLUDES` points to the Visual Studio-provided `SegmentHeap.cmake` script. The optional `VS_SEGMENT_HEAP_ALLOWLIST` and `VS_SEGMENT_HEAP_EXCLUDE` variables show how to include or exclude specific targets. If neither variable is set, Visual Studio enables Segment Heap for all targets. If both variables are set, `VS_SEGMENT_HEAP_ALLOWLIST` takes precedence.
+
## Run CMake from the command line or a CI pipeline
You can use the same *`CMakePresets.json`* and *`CMakeUserPresets.json`* files to invoke CMake in Visual Studio and from the command line. The [CMake](https://cmake.org/cmake/help/latest/manual/cmake.1.html) and [CTest](https://cmake.org/cmake/help/latest/manual/ctest.1.html) documentation are the best resources for invoking CMake and CTest with `--preset`. CMake version 3.20 or later is required.
diff --git a/docs/build/create-reusable-property-configurations.md b/docs/build/create-reusable-property-configurations.md
index 52af28e0f40..33a1075ce57 100644
--- a/docs/build/create-reusable-property-configurations.md
+++ b/docs/build/create-reusable-property-configurations.md
@@ -1,28 +1,35 @@
---
-description: "Learn more about: Share or reuse Visual Studio project settings"
-title: "Share or reuse Visual Studio project settings - C++"
-ms.date: 02/07/2022
+title: Share or reuse Visual Studio project settings - C++
+description: Learn how to create Visual Studio property sheets to share and reuse C++ project settings across projects. Simplify configuration with Property Manager.
+ms.date: 07/14/2026
helpviewer_keywords: ["project properties [C++], reusable"]
ms.topic: how-to
+#customer intent: As a C++ developer, I want to create a reusable property sheet using Property Manager so that I can share project settings across multiple projects.
---
# Share or reuse Visual Studio project settings
-To create a custom group of settings that you can share with others or reuse in multiple projects, use **Property Manager** to create a *property sheet* (a *`.props`* file) to store the settings for each kind of project that you want to be able to reuse or share with others. Using property sheets are far less error-prone than other ways of creating "global" settings.
+To create a custom group of settings that you can share with others or reuse in multiple projects, use **Property Manager** to create a *property sheet* (a *`.props`* file) to store the settings for each kind of project that you want to be able to reuse or share with others. Using property sheets is far less error-prone than other ways of creating "global" settings.
> [!IMPORTANT]
> **The problem with *`*.user`* files**
>
-> Past versions of Visual Studio used global property sheets that had a *`.user`* file name extension and were located in the *`\\AppData\Local\Microsoft\MSBuild\v4.0\`* folder. We no longer recommend these files because they set properties for project configurations on a per-user, per-computer basis. Such "global" settings can interfere with builds, especially when you are targeting more than one platform on your build computer. For example, if you have both an MFC project and Windows Phone project, the *`.user`* properties would be invalid for one of them. Reusable property sheets are more flexible and more robust.
+> Past versions of Visual Studio used global property sheets that had a *`.user`* file name extension and were located in the *`\\AppData\Local\Microsoft\MSBuild\v4.0\`* folder.
>
-> Although *`.user`* files are still installed by Visual Studio and participate in property inheritance, they're empty by default. The best practice is to delete any reference to them in **Property Manager** to ensure that your projects operate independently of any per-user, per-computer settings. This practice is important to ensure correct behavior in a SCC (source code control) environment.
+> Microsoft no longer recommends using this approach. These files set properties for project configurations on a per-user, per-computer basis. Such *global* settings can interfere with builds, especially when you are targeting more than one platform on your build computer. For example, if you have both an MFC project and Windows Phone project, the *`.user`* properties are invalid for one of them. Reusable property sheets are more flexible and more robust.
+>
+> Although Visual Studio still installs *`.user`* files and they participate in property inheritance, they're empty by default. The best practice is to delete any reference to them in **Property Manager** to ensure that your projects operate independently of any per-user, per-computer settings. This practice is important to ensure correct behavior in a source code control environment.
To display **Property Manager**, on the menu bar, choose **View** > **Property Manager** or **View** > **Other Windows** > **Property Manager**, depending on your settings.
-If you want to apply a common, frequently used set of properties to multiple projects, you can use **Property Manager** to capture them in a reusable *property sheet* file, which by convention has a *`.props`* file name extension. You can apply the sheet (or sheets) to new projects so you don't have to set those properties from scratch.
+If you want to apply a common, frequently used set of properties to multiple projects, use **Property Manager** to capture them in a reusable *property sheet* file, which by convention has a *`.props`* file name extension. You can apply the sheet (or sheets) to new projects so you don't have to set those properties from scratch.
+
+:::image type="content" source="media/add-new-project-property-sheet.png" alt-text="Screenshot of the Property Manager context menu.":::
+
+Under each configuration node, you see nodes for each property sheet that applies to that configuration. The system adds property sheets that set common values based on options you choose in the app wizard when you create the project. Right-click any node and choose **Properties** to see the properties that apply to that node.
-
+All the property sheets are imported automatically into the project's primary property sheet (*`ms.cpp.props`*) and are evaluated in the order they appear in **Property Manager**. You can move them to change the evaluation order. Property sheets that are evaluated later override the values in previously evaluated sheets.
-Under each configuration node, you see nodes for each property sheet that applies to that configuration. The system adds property sheets that set common values based on options you choose in the app wizard when you create the project. Right-click any node and choose Properties to see the properties that apply to that node. All the property sheets are imported automatically into the project's primary property sheet (*`ms.cpp.props`*) and are evaluated in the order they appear in Property Manager. You can move them to change the evaluation order. Property sheets that are evaluated later override the values in previously evaluated sheets. For more information about the order of evaluation in the *`.vcxproj`* file, the *`.props`* and *`.targets`* files, environment variables, and the command line, see [Project property inheritance](project-property-inheritance.md).
+For more information about the order of evaluation in the *`.vcxproj`* file, the *`.props`* and *`.targets`* files, environment variables, and the command line, see [Project property inheritance](project-property-inheritance.md).
If you choose **Add New Project Property Sheet** and then select, for example, the MyProps.props property sheet, a property page dialog box appears. Notice that it applies to the MyProps property sheet; any changes you make are written to the sheet, not to the project file (.vcxproj).
@@ -30,17 +37,20 @@ Properties in a property sheet are overridden if the same property is set direct
You can import a property sheet as often as required. Multiple projects in a solution can inherit settings from the same property sheet, and a project can have multiple sheets. A property sheet itself can inherit settings from another property sheet.
-You can also create a common property sheet for multiple configurations. To create a property sheet for each configuration, open the shortcut menu for one of them, choose **Add Existing Property Sheet**, and then add the other sheets. However, if you use a common property sheet, properties you set for all configurations that the sheet applies to. The IDE doesn't show which projects or other property sheets inherit from a given property sheet.
+You can also create a common property sheet for multiple configurations. To create a property sheet for each configuration, open the shortcut menu for one of them, choose **Add Existing Property Sheet**, and then add the other sheets. However, if you use a common property sheet, properties you set apply to all configurations that the sheet applies to. The IDE doesn't show which projects or other property sheets inherit from a given property sheet.
In large solutions that have many projects, it can be useful to create a common property sheet for all the projects in the solution. Create the property sheet as usual. Use **Property Manager** to add that property sheet to each project in the solution. If necessary at the project level, you can add another property sheet to set project-specific values.
> [!IMPORTANT]
-> A *`.props`* file by default does not participate in source control because it isn't created as a project item. You can manually add the file as a solution item if you want to include it in source control.
+> A *`.props`* file by default doesn't participate in source control because it isn't created as a project item. You can manually add the file as a solution item if you want to include it in source control.
#### To create a property sheet
1. On the menu bar, choose **View** > **Property Manager** or **View** > **Other Windows** > **Property Manager**. The **Property Manager** opens.
+1. Select the item to which to apply the property sheet. This item can be a particular configuration, or another property sheet.
+1. Right-click the item and then choose **Add New Project Property Sheet**.
+1. In the **Add New Item** dialog, specify a name and location for the property sheet. Visual Studio saves the *`.props`* file in the specified location.
-2. To define the scope of the property sheet, select the item to which it applies. This item can be a particular configuration, or another property sheet. Open the shortcut menu for this item and then choose **Add New Project Property Sheet**. Specify a name and location.
+ Expand the items under the project to see your property sheet.
-3. In **Property Manager**, open the new property sheet and then set the properties you want to include.
+1. In **Property Manager**, open the new property sheet and then set the properties you want to include.
diff --git a/docs/build/creating-and-managing-visual-cpp-projects.md b/docs/build/creating-and-managing-visual-cpp-projects.md
index 2441a8b327e..f72cbf8f850 100644
--- a/docs/build/creating-and-managing-visual-cpp-projects.md
+++ b/docs/build/creating-and-managing-visual-cpp-projects.md
@@ -1,29 +1,59 @@
---
-title: "Create and Configure Visual Studio C++ Projects"
-description: "Learn how to create a Visual Studio C++ project, and then add code and build your project."
-ms.date: 03/24/2025
+title: Create and Configure Visual Studio C++ Projects
+description: Get started with Visual Studio C++ projects. Learn to create a solution, then compile and run your code.
+ms.date: 07/15/2026
ms.topic: concept-article
helpviewer_keywords: ["Visual Studio C++ projects, creating", "projects [C++], creating", "Visual Studio C++ projects"]
---
# Visual Studio C++ projects
-A *Visual Studio project* is a collection of code files and assets such as icons, images, and so on, that are built together using the MSBuild system. MSBuild is the native build system for Visual Studio and is generally the best build system to use for Windows-specific programs. MSBuild is tightly integrated with Visual Studio, but you can also use it from the command line.
+A *Visual Studio project* is a collection of code files and assets such as icons, images, and other resources that you build together by using the MSBuild system. MSBuild is the native build system for Visual Studio and is generally the best build system to use for Windows-specific programs. Visual Studio tightly integrates with MSBuild, but you can also use MSBuild from the command line.
For information about upgrading MSBuild projects from older versions of Visual Studio, see the [Microsoft C++ porting and upgrading guide](../porting/visual-cpp-porting-and-upgrading-guide.md).
-For cross-platform projects, or projects that use open-source libraries, we recommend using [CMake projects in Visual Studio](cmake-projects-in-visual-studio.md).
+For cross-platform projects, or projects that use open-source libraries, use [CMake projects in Visual Studio](cmake-projects-in-visual-studio.md).
## Create a Visual Studio C++ project
-::: moniker range=">=msvc-160"
+When you open Visual Studio, you see options to open an existing project or create a new one. You can also open Visual Studio without code.
-1. Create a C++ project by choosing **File** > **New** > **Project**.
+::: moniker range=">=msvc-180"
-1. In the **Create a new project** dialog, set the **Language** dropdown to **C++**. This filters the list of project templates to C++ projects. You can filter the templates by setting the **Platform**, **Project Type**, or by entering keywords in the search box.
+1. Open Visual Studio and select **Create a new project**. If you already opened Visual Studio, create a C++ project by choosing **File** > **New** > **Project**.
- :::image type="content" source="../build/media/vs2019-choose-console-app.png" alt-text="Screenshot of the Create a new project wizard. The Console App project template is selected.":::
+1. In the **Create a new project** dialog, set the **Language** dropdown menu to **C++**. This option filters the list of project templates to C++ projects. You can filter the templates by setting the **Platform**, **Project Type**, or by entering keywords in the search box.
-1. Select a project template, then choose **Next**.
+ :::image type="content" source="media/vs-2026/choose-console-app.png" alt-text="Screenshot of the Create a new project dialog with the Console App project template selected.":::
+
+1. Select a project template, and then choose **Next**.
+
+1. On the **Configure your new project page**, enter project-specific settings such as the project name or location and then choose **Create** to create your project.
+
+::: moniker-end
+
+::: moniker range="msvc-170"
+
+1. Open Visual Studio and select **Create a new project**. If you already opened Visual Studio, create a C++ project by choosing **File** > **New** > **Project**.
+
+1. In the **Create a new project** dialog, set the **Language** dropdown menu to **C++**. This option filters the list of project templates to C++ projects. You can filter the templates by setting the **Platform**, **Project Type**, or by entering keywords in the search box.
+
+ :::image type="content" source="media/vs-2022/choose-console-app.png" alt-text="Screenshot of the Create a new project dialog with the Console App project template selected.":::
+
+1. Select a project template, and then choose **Next**.
+
+1. On the **Configure your new project page**, enter project-specific settings such as the project name or location and then choose **Create** to create your project.
+
+::: moniker-end
+
+::: moniker range="msvc-160"
+
+1. Open Visual Studio and select **Create a new project**. If you already opened Visual Studio, create a C++ project by choosing **File** > **New** > **Project**.
+
+1. In the **Create a new project** dialog, set the **Language** dropdown menu to **C++**. This option filters the list of project templates to C++ projects. You can filter the templates by setting the **Platform**, **Project Type**, or by entering keywords in the search box.
+
+ :::image type="content" source="../build/media/vs2019-choose-console-app.png" alt-text="Screenshot of the Create a new project dialog with the Console App project template selected.":::
+
+1. Select a project template, and then choose **Next**.
1. On the **Configure your new project page**, enter project-specific settings such as the project name or location and then choose **Create** to create your project.
@@ -31,7 +61,7 @@ For cross-platform projects, or projects that use open-source libraries, we reco
::: moniker range="msvc-150"
-1. Create a C++ project by choosing **File** > **New** > **Project**.
+1. Open Visual Studio and select **Create a new project**. If you already opened Visual Studio, create a C++ project by choosing **File** > **New** > **Project**.
1. Choose **Visual C++** in the left pane. In the center pane, a list of project templates appears:
@@ -43,9 +73,11 @@ For more information about the default project templates included in Visual Stud
You can create your own project templates. For more information, see [Create project templates](/visualstudio/ide/how-to-create-project-templates).
-After you create a project, it appears in the [Solution Explorer](/visualstudio/ide/solutions-and-projects-in-visual-studio) window:
+After you create a project, it appears in [Solution Explorer](/visualstudio/ide/solutions-and-projects-in-visual-studio):
-:::image type="content" source="media/mathlibrary-solution-explorer-153.png" alt-text="Screenshot of the Solution Explorer window, showing source files, header files, and resource files.":::
+:::image type="content" source="media/vs-2026/solution-explorer.png" alt-text="Screenshot of the Solution Explorer window, showing source files, header files, and resource files." lightbox="media/vs-2026/solution-explorer.png":::
+
+If you don't see **Solution Explorer**, from the main menu, select **View** > **Solution Explorer**.
When you create a new project, a solution file (*`.sln`*) is also created. A *Visual Studio solution* is a collection of one or more projects. You can add another project to the solution by right-clicking the solution name in **Solution Explorer** > **Add** > **New project**.
@@ -57,29 +89,30 @@ Add source code files, icons, or any other items to your project by right-clicki
## Add third-party libraries to a project
-Over 900 C++ open source libraries are available via the [vcpkg](/vcpkg/) package manager. Run the Visual Studio integration step to set up the paths to that library when you reference it from any Visual Studio project.
+Over 900 C++ open source libraries are available through the [vcpkg](/vcpkg/) package manager. Run the Visual Studio integration step to set up the paths to those libraries when you reference them from any Visual Studio project.
+
+For more information about consuming a library that you download by using the **vcpkg** package manager, see:
-For more information about consuming a library that you have downloaded by using the **vcpkg** package manager, see:
- [vcpkg in CMake projects](/vcpkg/users/buildsystems/cmake-integration)
- [Install and use packages with CMake in Visual Studio](/vcpkg/get_started/get-started-vs)
- [vcpkg in MSBuild projects](/vcpkg/users/buildsystems/msbuild-integration)
- [Tutorial: Install and use packages with MSBuild in Visual Studio](/vcpkg/get_started/get-started-msbuild)
-There are also commercial third-party libraries that you can install. Follow their installation instructions.
+You can also install commercial third-party libraries. Follow their installation instructions.
## Set compiler options and build properties
-To configure build settings for a project, right-click on the project in **Solution Explorer** and choose **Properties**. For more information, see [Set compiler and build properties](working-with-project-properties.md).
+To configure build settings for a project, in **Solution Explorer**, right-click the project and choose **Properties**. For more information, see [Set compiler and build properties](working-with-project-properties.md).
## Compile and run a project
-To compile and run the new project, press **F5** or select the *debug dropdown* with the green arrow on the main toolbar. The *configuration dropdown* is where you choose whether to perform a *Debug* or *Release* build (or some other custom configuration).
+To compile and run the new project, press **F5** or select the **debug dropdown list** with the green arrow on the main toolbar. Use the **configuration dropdown list** to choose whether to perform a **Debug** or **Release** build, or some custom configuration.
-A new project compiles without errors. When adding your own code, you might occasionally introduce an error or trigger a warning. An error prevents the build from completing; a warning doesn't. All errors and warnings appear both in the Output Window and in the Error List when you build the project.
+A new project compiles without errors. When you add your own code, you might occasionally introduce an error or trigger a warning. An error prevents the build from completing. A warning doesn't. All errors and warnings appear both in the **Output** window and in the **Error List**.
-:::image type="content" source="../overview/media/vs2017-output-error-list.png" alt-text="Screenshot of the Output window and Error list, showing a syntax error for a misplaced colon.":::
+:::image type="content" source="media/vs-2026/output-error-list.png" alt-text="Screenshot of the Output window and Error list, showing a syntax error for a typo in a variable name.":::
-In the **Error List**, you can press **F1** on the highlighted error to go to its documentation topic.
+In the **Error List**, press **F1** on the highlighted error to go to its documentation topic.
## Related content
diff --git a/docs/build/exception-handling-x64.md b/docs/build/exception-handling-x64.md
index 8e35eb70ffd..efb1eac2d73 100644
--- a/docs/build/exception-handling-x64.md
+++ b/docs/build/exception-handling-x64.md
@@ -9,27 +9,31 @@ ms.assetid: 41fecd2d-3717-4643-b21c-65dcd2f18c93
An overview of structured exception handling and C++ exception handling coding conventions and behavior on the x64. For general information on exception handling, see [Exception Handling in Microsoft C++](../cpp/exception-handling-in-visual-cpp.md).
-## Unwind data for exception handling, debugger support
+## Unwind data for exception handling and debugger support
-Several data structures are required for exception handling and debugging support.
+To recover nonvolatile registers when an exception is handled, nonleaf functions are annotated with static data. This data, commonly referred to as "Function Unwind Information", describes how to properly unwind the function at an arbitrary instruction. This data is stored as *pdata*, or procedure data, which in turn refers to *xdata*, the exception handling data.
+
+The Function Unwind Information is composed of several data structures, described next.
+
+For Unwind Information supporting the Intel APX (Advanced Performance Extensions), see the [Unwind V3 Preview Specification](../build/x64-unwind-information-v3.md).
### struct RUNTIME_FUNCTION
Table-based exception handling requires a table entry for all functions that allocate stack space or call another function (for example, nonleaf functions). Function table entries have the format:
-|Size|Value|
+| Size | Value |
|-|-|
|ULONG|Function start address|
|ULONG|Function end address|
|ULONG|Unwind info address|
-The RUNTIME_FUNCTION structure must be DWORD aligned in memory. All addresses are image relative, that is, they're 32-bit offsets from the starting address of the image that contains the function table entry. These entries are sorted, and put in the .pdata section of a PE32+ image. For dynamically generated functions [JIT compilers], the runtime to support these functions must either use RtlInstallFunctionTableCallback or RtlAddFunctionTable to provide this information to the operating system. Failure to do so will result in unreliable exception handling and debugging of processes.
+The `RUNTIME_FUNCTION` structure must be `DWORD` aligned in memory. All addresses are image relative, that is, they're 32-bit offsets from the starting address of the image that contains the function table entry. These entries are sorted, and put in the `.pdata` section of a PE32+ image. For dynamically generated functions [JIT compilers], the runtime to support these functions must either use `RtlInstallFunctionTableCallback` or `RtlAddFunctionTable` to provide this information to the operating system. Failure to do so results in unreliable exception handling and debugging of processes.
### struct UNWIND_INFO
-The unwind data info structure is used to record the effects a function has on the stack pointer, and where the nonvolatile registers are saved on the stack:
+The unwind data info structure records the effects a function has on the stack pointer and where the nonvolatile registers are saved on the stack:
-|Size|Value|
+| Size | Value |
|-|-|
|UBYTE: 3|Version|
|UBYTE: 5|Flags|
@@ -42,20 +46,20 @@ The unwind data info structure is used to record the effects a function has on t
(1) Exception Handler
-|Size|Value|
+| Size | Value |
|-|-|
|ULONG|Address of exception handler|
|variable|Language-specific handler data (optional)|
(2) Chained Unwind Info
-|Size|Value|
+| Size | Value |
|-|-|
|ULONG|Function start address|
|ULONG|Function end address|
|ULONG|Unwind info address|
-The UNWIND_INFO structure must be DWORD aligned in memory. Here's what each field means:
+The `UNWIND_INFO` structure must be `DWORD` aligned in memory. Here's what each field means:
- **Version**
@@ -67,9 +71,9 @@ The UNWIND_INFO structure must be DWORD aligned in memory. Here's what each fiel
|Flag|Description|
|-|-|
- |`UNW_FLAG_EHANDLER`| The function has an exception handler that should be called when looking for functions that need to examine exceptions.|
- |`UNW_FLAG_UHANDLER`| The function has a termination handler that should be called when unwinding an exception.|
- |`UNW_FLAG_CHAININFO`| This unwind info structure is not the primary one for the procedure. Instead, the chained unwind info entry is the contents of a previous RUNTIME_FUNCTION entry. For information, see [Chained unwind info structures](#chained-unwind-info-structures). If this flag is set, then the UNW_FLAG_EHANDLER and UNW_FLAG_UHANDLER flags must be cleared. Also, the frame register and fixed-stack allocation fields must have the same values as in the primary unwind info.|
+ |`UNW_FLAG_EHANDLER`| The function has an exception handler that the operating system calls to examine the state of the exception and potentially handle it. Language features such as the C `__try` clause register such a handler.|
+ |`UNW_FLAG_UHANDLER`| The function has a termination handler that the operation system calls when unwinding the stack. This handler could release resources allocated by the function in exception safe code. Language features such as local C++ object destructors and C `__finally` clauses register such a termination handler. |
+ |`UNW_FLAG_CHAININFO`| This unwind info structure isn't the primary one for the procedure. Instead, the chained unwind info entry is the contents of a previous `RUNTIME_FUNCTION` entry. For information, see [Chained unwind info structures](#chained-unwind-info-structures). If this flag is set, then the `UNW_FLAG_EHANDLER` and `UNW_FLAG_UHANDLER` flags must be cleared. Also, the frame register and fixed-stack allocation fields must have the same values as in the primary unwind info.|
- **Size of prolog**
@@ -77,23 +81,23 @@ The UNWIND_INFO structure must be DWORD aligned in memory. Here's what each fiel
- **Count of unwind codes**
- The number of slots in the unwind codes array. Some unwind codes, for example, UWOP_SAVE_NONVOL, require more than one slot in the array.
+ The number of slots in the unwind codes array. Some unwind codes, such as `UWOP_SAVE_NONVOL`, require more than one slot in the array.
- **Frame register**
- If nonzero, then the function uses a frame pointer (FP), and this field is the number of the nonvolatile register used as the frame pointer, using the same encoding for the operation info field of UNWIND_CODE nodes.
+ If nonzero, the function uses a frame pointer (FP), and this field is the number of the nonvolatile register used as the frame pointer, using the same encoding for the operation info field of `UNWIND_CODE` nodes.
- **Frame register offset (scaled)**
- If the frame register field is nonzero, this field is the scaled offset from RSP that is applied to the FP register when it's established. The actual FP register is set to RSP + 16 \* this number, allowing offsets from 0 to 240. This offset permits pointing the FP register into the middle of the local stack allocation for dynamic stack frames, allowing better code density through shorter instructions. (That is, more instructions can use the 8-bit signed offset form.)
+ This field is a scaled offset between the `RSP` register value and the selected Frame Pointer (FP) register value. The selected FP register is set to `RSP` + 16 * this number, which means you can use offsets from 0 to 240. This offset points the FP register into the middle of the local stack allocation for dynamic stack frames, so you get better code density through shorter instructions. (That is, more instructions can use the 8-bit signed offset form.)
- **Unwind codes array**
- An array of items that explains the effect of the prolog on the nonvolatile registers and RSP. See the section on UNWIND_CODE for the meanings of individual items. For alignment purposes, this array always has an even number of entries, and the final entry is potentially unused. In that case, the array is one longer than indicated by the count of unwind codes field.
+ An array of items that explains the effect of the prolog on the nonvolatile registers and `RSP`. See the section on [Unwind operations code](#unwind-operation-code) for the meanings of individual items. To maintain proper data alignment, this array always contains an even number of entries, and the final entry may be unused. In that case, the array is one longer than indicated by the count of unwind codes field.
- **Address of exception handler**
- An image-relative pointer to either the function's language-specific exception or termination handler, if flag UNW_FLAG_CHAININFO is clear and one of the flags UNW_FLAG_EHANDLER or UNW_FLAG_UHANDLER is set.
+ An image-relative pointer to either the function's language-specific exception or termination handler, if flag `UNW_FLAG_CHAININFO` is clear and one of the flags `UNW_FLAG_EHANDLER` or `UNW_FLAG_UHANDLER` is set.
- **Language-specific handler data**
@@ -101,13 +105,13 @@ The UNWIND_INFO structure must be DWORD aligned in memory. Here's what each fiel
- **Chained Unwind Info**
- If flag UNW_FLAG_CHAININFO is set, then the UNWIND_INFO structure ends with three UWORDs. These UWORDs represent the RUNTIME_FUNCTION information for the function of the chained unwind.
+ If flag `UNW_FLAG_CHAININFO` is set, the `UNWIND_INFO` structure ends with three `UWORD`s. These `UWORD`s represent the `RUNTIME_FUNCTION` information for the function of the chained unwind.
### struct UNWIND_CODE
-The unwind code array is used to record the sequence of operations in the prolog that affect the nonvolatile registers and RSP. Each code item has this format:
+Use the unwind code array to record the sequence of operations in the prolog that affect the nonvolatile registers and `RSP`. Each code item has this format:
-|Size|Value|
+| Size | Value |
|-|-|
|UBYTE|Offset in prolog|
|UBYTE: 4|Unwind operation code|
@@ -121,17 +125,17 @@ Offset (from the beginning of the prolog) of the end of the instruction that per
#### Unwind operation code
-Note: Certain operation codes require an unsigned offset to a value in the local stack frame. This offset is from the start, that is, the lowest address of the fixed stack allocation. If the Frame Register field in the UNWIND_INFO is zero, this offset is from RSP. If the Frame Register field is nonzero, this offset is from where RSP was located when the FP register was established. It equals the FP register minus the FP register offset (16 \* the scaled frame register offset in the UNWIND_INFO). If an FP register is used, then any unwind code taking an offset must only be used after the FP register is established in the prolog.
+Certain operation codes require an unsigned offset to a value in the local stack frame. This offset is from the start, that is, the lowest address of the fixed stack allocation. If the Frame Register field in the `UNWIND_INFO` is zero, this offset is from `RSP`. If the Frame Register field is nonzero, this offset is from where `RSP` was located when the FP register was established. It equals the FP register minus the FP register offset (16 \* the scaled frame register offset in the `UNWIND_INFO`). If an FP register is used, then any unwind code taking an offset must only be used after the FP register is established in the prolog.
-For all opcodes except `UWOP_SAVE_XMM128` and `UWOP_SAVE_XMM128_FAR`, the offset is always a multiple of 8, because all stack values of interest are stored on 8-byte boundaries (the stack itself is always 16-byte aligned). For operation codes that take a short offset (less than 512K), the final USHORT in the nodes for this code holds the offset divided by 8. For operation codes that take a long offset (512K <= offset < 4GB), the final two USHORT nodes for this code hold the offset (in little-endian format).
+For all opcodes except `UWOP_SAVE_XMM128` and `UWOP_SAVE_XMM128_FAR`, the offset is always a multiple of 8, because all stack values of interest are stored on 8-byte boundaries (the stack itself is always 16-byte aligned). For operation codes that take a short offset (less than 512K), the final `USHORT` in the nodes for this code holds the offset divided by 8. For operation codes that take a long offset (512K <= offset < 4GB), the final two `USHORT` nodes for this code hold the offset (in little-endian format).
-For the opcodes `UWOP_SAVE_XMM128` and `UWOP_SAVE_XMM128_FAR`, the offset is always a multiple of 16, since all 128-bit XMM operations must occur on 16-byte aligned memory. Therefore, a scale factor of 16 is used for `UWOP_SAVE_XMM128`, permitting offsets of less than 1M.
+For the opcodes `UWOP_SAVE_XMM128` and `UWOP_SAVE_XMM128_FAR`, the offset is always a multiple of 16, since all 128-bit `XMM` operations must occur on 16-byte aligned memory. Therefore, a scale factor of 16 is used for `UWOP_SAVE_XMM128`, permitting offsets of less than 1M.
The unwind operation code is one of these values:
- `UWOP_PUSH_NONVOL` (0) 1 node
- Push a nonvolatile integer register, decrementing RSP by 8. The operation info is the number of the register. Because of the constraints on epilogs, `UWOP_PUSH_NONVOL` unwind codes must appear first in the prolog and correspondingly, last in the unwind code array. This relative ordering applies to all other unwind codes except `UWOP_PUSH_MACHFRAME`.
+ Push a nonvolatile integer register, decrementing `RSP` by 8. The operation info is the number of the register. Because of the constraints on epilogs, `UWOP_PUSH_NONVOL` unwind codes must appear first in the prolog and correspondingly, last in the unwind code array. This relative ordering applies to all other unwind codes except `UWOP_PUSH_MACHFRAME`.
- `UWOP_ALLOC_LARGE` (1) 2 or 3 nodes
@@ -151,7 +155,7 @@ The unwind operation code is one of these values:
- `UWOP_SET_FPREG` (3) 1 node
- Establish the frame pointer register by setting the register to some offset of the current RSP. The offset is equal to the Frame Register offset (scaled) field in the UNWIND_INFO \* 16, allowing offsets from 0 to 240. The use of an offset permits establishing a frame pointer that points to the middle of the fixed stack allocation, helping code density by allowing more accesses to use short instruction forms. The operation info field is reserved and shouldn't be used.
+ Establish the frame pointer register by setting the register to some offset of the current `RSP`. The offset is equal to the Frame Register offset (scaled) field in the `UNWIND_INFO` \* 16, allowing offsets from 0 to 240. The use of an offset permits establishing a frame pointer that points to the middle of the fixed stack allocation, helping code density by allowing more accesses to use short instruction forms. The operation info field is reserved and shouldn't be used.
- `UWOP_SAVE_NONVOL` (4) 2 nodes
@@ -163,52 +167,52 @@ The unwind operation code is one of these values:
- `UWOP_SAVE_XMM128` (8) 2 nodes
- Save all 128 bits of a nonvolatile XMM register on the stack. The operation info is the number of the register. The scaled-by-16 stack offset is recorded in the next slot.
+ Save all 128 bits of a nonvolatile `XMM` register on the stack. The operation info is the number of the register. The scaled-by-16 stack offset is recorded in the next slot.
- `UWOP_SAVE_XMM128_FAR` (9) 3 nodes
- Save all 128 bits of a nonvolatile XMM register on the stack with a long offset. The operation info is the number of the register. The unscaled stack offset is recorded in the next two slots.
+ Save all 128 bits of a nonvolatile `XMM` register on the stack with a long offset. The operation info is the number of the register. The unscaled stack offset is recorded in the next two slots.
- `UWOP_PUSH_MACHFRAME` (10) 1 node
- Push a machine frame. This unwind code is used to record the effect of a hardware interrupt or exception. There are two forms. If the operation info equals 0, one of these frames has been pushed on the stack:
+ Push a machine frame. This unwind code records the effect of a hardware interrupt or exception. It has two forms. A value of 0, indicates hardware has pushed a frame such as this on the stack:
|Location|Value|
|-|-|
- |RSP+32|SS|
- |RSP+24|Old RSP|
- |RSP+16|EFLAGS|
- |RSP+8|CS|
- |RSP|RIP|
+ |`RSP`+32|`SS`|
+ |`RSP`+24|Old `RSP`|
+ |`RSP`+16|`EFLAGS`|
+ |`RSP`+8|`CS`|
+ |`RSP`|`RIP`|
- If the operation info equals 1, then one of these frames has been pushed:
+ A value of 1, indicates hardware has pushed a frame such as this on the stack:
|Location|Value|
|-|-|
- |RSP+40|SS|
- |RSP+32|Old RSP|
- |RSP+24|EFLAGS|
- |RSP+16|CS|
- |RSP+8|RIP|
- |RSP|Error code|
+ |`RSP`+40|`SS`|
+ |`RSP`+32|Old `RSP`|
+ |`RSP`+24|`EFLAGS`|
+ |`RSP`+16|`CS`|
+ |`RSP`+8|`RIP`|
+ |`RSP`|Error code|
This unwind code always appears in a dummy prolog, which is never actually executed, but instead appears before the real entry point of an interrupt routine, and exists only to provide a place to simulate the push of a machine frame. `UWOP_PUSH_MACHFRAME` records that simulation, which indicates the machine has conceptually done this operation:
- 1. Pop RIP return address from top of stack into *Temp*
+ 1. Pop `RIP` return address from top of stack into *Temp*
- 1. Push SS
+ 1. Push `SS`
- 1. Push old RSP
+ 1. Push old `RSP`
- 1. Push EFLAGS
+ 1. Push `EFLAGS`
- 1. Push CS
+ 1. Push `CS`
1. Push *Temp*
1. Push Error Code (if op info equals 1)
- The simulated `UWOP_PUSH_MACHFRAME` operation decrements RSP by 40 (op info equals 0) or 48 (op info equals 1).
+ The simulated `UWOP_PUSH_MACHFRAME` operation decrements `RSP` by 40 (if op info equals 0) or 48 (if op info equals 1).
#### Operation info
@@ -216,57 +220,57 @@ The meaning of the operation info bits depends upon the operation code. To encod
|Bit|Register|
|-|-|
-|0|RAX|
-|1|RCX|
-|2|RDX|
-|3|RBX|
-|4|RSP|
-|5|RBP|
-|6|RSI|
-|7|RDI|
-|8 to 15|R8 to R15|
+|0|`RAX`|
+|1|`RCX`|
+|2|`RDX`|
+|3|`RBX`|
+|4|`RSP`|
+|5|`RBP`|
+|6|`RSI`|
+|7|`RDI`|
+|8 to 15|`R8` to `R15`|
### Chained unwind info structures
-If the UNW_FLAG_CHAININFO flag is set, then an unwind info structure is a secondary one, and the shared exception-handler/chained-info address field contains the primary unwind information. This sample code retrieves the primary unwind information, assuming that `unwindInfo` is the structure that has the UNW_FLAG_CHAININFO flag set.
+If the `UNW_FLAG_CHAININFO` flag is set, then an unwind info structure is a secondary one, and the shared exception-handler/chained-info address field contains the primary unwind information. This sample code retrieves the primary unwind information, assuming that `unwindInfo` is the structure that has the `UNW_FLAG_CHAININFO` flag set.
```cpp
PRUNTIME_FUNCTION primaryUwindInfo = (PRUNTIME_FUNCTION)&(unwindInfo->UnwindCode[( unwindInfo->CountOfCodes + 1 ) & ~1]);
```
-Chained info is useful in two situations. First, it can be used for noncontiguous code segments. By using chained info, you can reduce the size of the required unwind information, because you do not have to duplicate the unwind codes array from the primary unwind info.
+Chained info is useful in two situations. First, it can be used for noncontiguous code segments. By using chained info, you can reduce the size of the required unwind information, because you don't have to duplicate the unwind codes array from the primary unwind info.
-You can also use chained info to group volatile register saves. The compiler may delay saving some volatile registers until it is outside of the function entry prolog. You can record them by having primary unwind info for the portion of the function before the grouped code, and then setting up chained info with a non-zero size of prolog, where the unwind codes in the chained info reflect saves of the nonvolatile registers. In that case, the unwind codes are all instances of UWOP_SAVE_NONVOL. A grouping that saves nonvolatile registers by using a PUSH or modifies the RSP register by using an additional fixed stack allocation is not supported.
+You can also use chained info to group volatile register saves. The compiler might delay saving some volatile registers until it is outside of the function entry prolog. You can record them by having primary unwind info for the portion of the function before the grouped code, and then setting up chained info with a nonzero size of prolog, where the unwind codes in the chained info reflect saves of the nonvolatile registers. In that case, the unwind codes are all instances of `UWOP_SAVE_NONVOL`. A grouping that saves nonvolatile registers by using a `PUSH` or modifies the `RSP` register by using an additional fixed stack allocation isn't supported.
-An UNWIND_INFO item that has UNW_FLAG_CHAININFO set can contain a RUNTIME_FUNCTION entry whose UNWIND_INFO item also has UNW_FLAG_CHAININFO set, sometimes called *multiple shrink-wrapping*. Eventually, the chained unwind info pointers arrive at an UNWIND_INFO item that has UNW_FLAG_CHAININFO cleared. This item is the primary UNWIND_INFO item, which points to the actual procedure entry point.
+An `UNWIND_INFO` item that has `UNW_FLAG_CHAININFO` set can contain a `RUNTIME_FUNCTION` entry whose `UNWIND_INFO` item also has `UNW_FLAG_CHAININFO` set, sometimes called *multiple shrink-wrapping*. Eventually, the chained unwind info pointers arrive at an `UNWIND_INFO` item that has `UNW_FLAG_CHAININFO` cleared. This item is the primary `UNWIND_INFO` item, which points to the actual procedure entry point.
## Unwind procedure
-The unwind code array is sorted into descending order. When an exception occurs, the complete context is stored by the operating system in a context record. The exception dispatch logic is then invoked, which repeatedly executes these steps to find an exception handler:
+The unwind code array is sorted into descending order. When an exception occurs, the operating system stores the complete context in a context record. The exception dispatch logic is then invoked, which repeatedly executes these steps to find an exception handler:
-1. Use the current RIP stored in the context record to search for a RUNTIME_FUNCTION table entry that describes the current function (or function portion, for chained UNWIND_INFO entries).
+1. Use the current `RIP` stored in the context record to search for a `RUNTIME_FUNCTION` table entry that describes the current function (or function portion, for chained `UNWIND_INFO` entries).
-1. If no function table entry is found, then it's in a leaf function, and RSP directly addresses the return pointer. The return pointer at [RSP] is stored in the updated context, the simulated RSP is incremented by 8, and step 1 is repeated.
+1. If the search doesn't find a function table entry, the code is assumed to be part of a leaf function, and `RSP` directly addresses the return pointer. The return pointer at [`RSP`] is stored in the updated context, the simulated `RSP` is incremented by 8, and step 1 is repeated.
-1. If a function table entry is found, RIP can lie within three regions: a) in an epilog, b) in the prolog, or c) in code that may be covered by an exception handler.
+1. If the search finds a function table entry, `RIP` can lie within three regions: a) in an epilog, b) in the prolog, or c) in code that might be covered by an exception handler.
- - Case a) If the RIP is within an epilog, then control is leaving the function, there can be no exception handler associated with this exception for this function, and the effects of the epilog must be continued to compute the context of the caller function. To determine if the RIP is within an epilog, the code stream from RIP onward is examined. If that code stream can be matched to the trailing portion of a legitimate epilog, then it's in an epilog, and the remaining portion of the epilog is simulated, with the context record updated as each instruction is processed. After this processing, step 1 is repeated.
+ - Case a) If the `RIP` is within an epilog, control is leaving the function. There can be no exception handler associated with this exception for this function. The effects of the epilog must continue to compute the context of the caller function. To determine if the `RIP` is within an epilog, the code stream from `RIP` onward is examined. If that code stream matches the trailing portion of a legitimate epilog, it's in an epilog. The remaining portion of the epilog is simulated, with the context record updated as each instruction is processed. After this processing, step 1 is repeated.
- - Case b) If the RIP lies within the prologue, then control hasn't entered the function, there can be no exception handler associated with this exception for this function, and the effects of the prolog must be undone to compute the context of the caller function. The RIP is within the prolog if the distance from the function start to the RIP is less than or equal to the prolog size encoded in the unwind info. The effects of the prolog are unwound by scanning forward through the unwind codes array for the first entry with an offset less than or equal to the offset of the RIP from the function start, then undoing the effect of all remaining items in the unwind code array. Step 1 is then repeated.
+ - Case b) If the `RIP` lies within the prolog, control hasn't entered the function. There can be no exception handler associated with this exception for this function. The effects of the prolog must be undone to compute the context of the caller function. The `RIP` is within the prolog if the distance from the function start to the `RIP` is less than or equal to the prolog size encoded in the unwind info. The unwinder scans forward through the unwind codes array for the first entry with an offset less than or equal to the offset of the `RIP` from the function start, then undoes the effect of all remaining items in the unwind code array. Step 1 is then repeated.
- - Case c) If the RIP isn't within a prolog or epilog, and the function has an exception handler (UNW_FLAG_EHANDLER is set), then the language-specific handler is called. The handler scans its data and calls filter functions as appropriate. The language-specific handler can return that the exception was handled or that the search is to be continued. It can also initiate an unwind directly.
+ - Case c) If the `RIP` isn't within a prolog or epilog, and the function has an exception handler (`UNW_FLAG_EHANDLER` is set), the language-specific handler is called. The handler scans its data and calls filter functions as appropriate. The language-specific handler can return that the exception was handled or that the search is to be continued. It can also initiate an unwind directly.
-1. If the language-specific handler returns a handled status, then execution is continued using the original context record.
+1. If the language-specific handler returns a handled status, execution continues by using the original context record.
-1. If there's no language-specific handler or the handler returns a "continue search" status, then the context record must be unwound to the state of the caller. It's done by processing all of the unwind code array elements, undoing the effect of each. Step 1 is then repeated.
+1. If there's no language-specific handler or the handler returns a "continue search" status, the context record must be unwound to the state of the caller. The unwinder undoes the effect of each element in the unwind code array. Step 1 is then repeated.
-When chained unwind info is involved, these basic steps are still followed. The only difference is that, while walking the unwind code array to unwind a prolog's effects, once the end of the array is reached, it's then linked to the parent unwind info and the entire unwind code array found there is walked. This linking continues until arriving at an unwind info without the UNW_CHAINED_INFO flag, and then it finishes walking its unwind code array.
+When chained unwind info is involved, these basic steps are still followed. The only difference is that, while walking the unwind code array to unwind a prolog's effects, once the process reaches the end of the array, it links to the parent unwind info and walks the entire unwind code array found there. This linking continues until arriving at an unwind info without the `UNW_CHAINED_INFO` flag, and then it finishes walking its unwind code array.
-The smallest set of unwind data is 8 bytes. This would represent a function that only allocated 128 bytes of stack or less, and possibly saved one nonvolatile register. It's also the size of a chained unwind info structure for a zero-length prolog with no unwind codes.
+The smallest set of unwind data is 8 bytes. Such set represents a function that only allocated 128 bytes of stack or less, and possibly saved one nonvolatile register. It's also the size of a chained unwind info structure for a zero-length prolog with no unwind codes.
## Language-specific handler
-The relative address of the language-specific handler is present in the UNWIND_INFO whenever flags UNW_FLAG_EHANDLER or UNW_FLAG_UHANDLER are set. As described in the previous section, the language-specific handler is called as part of the search for an exception handler or as part of an unwind. It has this prototype:
+The `UNWIND_INFO` structure provides the relative address of the language-specific handler when either `UNW_FLAG_EHANDLER` or `UNW_FLAG_UHANDLER` flags are set. As described in the previous section, the search for an exception handler or the process of unwinding calls the language-specific handler. The handler uses this prototype:
```cpp
typedef EXCEPTION_DISPOSITION (*PEXCEPTION_ROUTINE) (
@@ -298,15 +302,15 @@ typedef struct _DISPATCHER_CONTEXT {
} DISPATCHER_CONTEXT, *PDISPATCHER_CONTEXT;
```
-**ControlPc** is the value of RIP within this function. This value is either an exception address or the address at which control left the establishing function. The RIP is used to determine if control is within some guarded construct inside this function, for example, a **`__try`** block for **`__try`**/**`__except`** or **`__try`**/**`__finally`**.
+**ControlPc** is the value of `RIP` within this function. This value is either an exception address or the address at which control left the establishing function. The `RIP` is used to determine if control is within some guarded construct inside this function, for example, a **`__try`** block for **`__try`**/**`__except`** or **`__try`**/**`__finally`**.
-**ImageBase** is the image base (load address) of the module containing this function, to be added to the 32-bit offsets used in the function entry and unwind info to record relative addresses.
+**ImageBase** is the image base (load address) of the module containing this function. The 32-bit offsets used in the function entry and unwind info should be added to the ImageBase obtain the final address.
-**FunctionEntry** supplies a pointer to the RUNTIME_FUNCTION function entry holding the function and unwind info image-base relative addresses for this function.
+**FunctionEntry** supplies a pointer to the `RUNTIME_FUNCTION` function entry holding the function and unwind info image-base relative addresses for this function.
**EstablisherFrame** is the address of the base of the fixed stack allocation for this function.
-**TargetIp** Supplies an optional instruction address that specifies the continuation address of the unwind. This address is ignored if **EstablisherFrame** isn't specified.
+**TargetIp** supplies an optional instruction address that specifies the continuation address of the unwind. This address is ignored if **EstablisherFrame** isn't specified.
**ContextRecord** points to the exception context, for use by the system exception dispatch/unwind code.
@@ -316,19 +320,19 @@ typedef struct _DISPATCHER_CONTEXT {
## Unwind helpers for MASM
-In order to write proper assembly routines, there's a set of pseudo-operations that can be used in parallel with the actual assembly instructions to create the appropriate .pdata and .xdata. And, there's a set of macros that provide simplified use of the pseudo-operations for their most common uses.
+To write proper assembly routines, use a set of pseudo-operations alongside the actual assembly instructions. These pseudo-operations create the appropriate `.pdata` and `.xdata`. Also, use a set of macros that simplify the use of these pseudo-operations for their most common uses.
### Raw pseudo-operations
|Pseudo operation|Description|
|-|-|
-|PROC FRAME \[:*ehandler*]|Causes MASM to generate a function table entry in .pdata and unwind information in .xdata for a function's structured exception handling unwind behavior. If *ehandler* is present, this proc is entered in the .xdata as the language-specific handler.
When the FRAME attribute is used, it must be followed by an .ENDPROLOG directive. If the function is a leaf function (as defined in [Function types](../build/stack-usage.md#function-types)) the FRAME attribute is unnecessary, as are the remainder of these pseudo-operations.|
-|.PUSHREG *register*|Generates a UWOP_PUSH_NONVOL unwind code entry for the specified register number using the current offset in the prologue.
Only use it with nonvolatile integer registers. For pushes of volatile registers, use an .ALLOCSTACK 8, instead|
-|.SETFRAME *register*, *offset*|Fills in the frame register field and offset in the unwind information using the specified register and offset. The offset must be a multiple of 16 and less than or equal to 240. This directive also generates a UWOP_SET_FPREG unwind code entry for the specified register using the current prologue offset.|
-|.ALLOCSTACK *size*|Generates a UWOP_ALLOC_SMALL or a UWOP_ALLOC_LARGE with the specified size for the current offset in the prologue.
The *size* operand must be a multiple of 8.|
-|.SAVEREG *register*, *offset*|Generates either a UWOP_SAVE_NONVOL or a UWOP_SAVE_NONVOL_FAR unwind code entry for the specified register and offset using the current prologue offset. MASM chooses the most efficient encoding.
*offset* must be positive, and a multiple of 8. *offset* is relative to the base of the procedure's frame, which is generally in RSP, or, if using a frame pointer, the unscaled frame pointer.|
-|.SAVEXMM128 *register*, *offset*|Generates either a UWOP_SAVE_XMM128 or a UWOP_SAVE_XMM128_FAR unwind code entry for the specified XMM register and offset using the current prologue offset. MASM chooses the most efficient encoding.
*offset* must be positive, and a multiple of 16. *offset* is relative to the base of the procedure's frame, which is generally in RSP, or, if using a frame pointer, the unscaled frame pointer.|
-|.PUSHFRAME \[*code*]|Generates a UWOP_PUSH_MACHFRAME unwind code entry. If the optional *code* is specified, the unwind code entry is given a modifier of 1. Otherwise the modifier is 0.|
+|PROC FRAME \[:*ehandler*]|Causes MASM to generate a function table entry in `.pdata` and unwind information in `.xdata` for a function's structured exception handling unwind behavior. If *ehandler* is present, this proc is entered in the .xdata as the language-specific handler.
When you use the FRAME attribute, follow it with an .ENDPROLOG directive. If the function is a leaf function (as defined in [Function types](../build/stack-usage.md#function-types)), the FRAME attribute is unnecessary, as are the remainder of these pseudo-operations.|
+|.PUSHREG *register*|Generates a `UWOP_PUSH_NONVOL` unwind code entry for the specified register number using the current offset in the prologue.
Only use it with nonvolatile integer registers. For pushes of volatile registers, use an .ALLOCSTACK 8, instead.|
+|.SETFRAME *register*, *offset*|Fills in the frame register field and offset in the unwind information using the specified register and offset. The offset must be a multiple of 16 and less than or equal to 240. This directive also generates a `UWOP_SET_FPREG` unwind code entry for the specified register using the current prologue offset.|
+|.ALLOCSTACK *size*|Generates a `UWOP_ALLOC_SMALL` or a `UWOP_ALLOC_LARGE` with the specified size for the current offset in the prologue.
The *size* operand must be a multiple of 8.|
+|.SAVEREG *register*, *offset*|Generates either a `UWOP_SAVE_NONVOL` or a `UWOP_SAVE_NONVOL_FAR` unwind code entry for the specified register and offset using the current prologue offset. MASM chooses the most efficient encoding.
*offset* must be positive, and a multiple of 8. *offset* is relative to the base of the procedure's frame, which is generally in `RSP`, or, if using a frame pointer, the unscaled frame pointer.|
+|.SAVEXMM128 *register*, *offset*|Generates either a `UWOP_SAVE_XMM128` or a `UWOP_SAVE_XMM128_FAR` unwind code entry for the specified `XMM` register and offset using the current prologue offset. MASM chooses the most efficient encoding.
*offset* must be positive, and a multiple of 16. *offset* is relative to the base of the procedure's frame, which is generally in `RSP`, or, if using a frame pointer, the unscaled frame pointer.|
+|.PUSHFRAME \[*code*]|Generates a `UWOP_PUSH_MACHFRAME` unwind code entry. If you specify the optional *code*, the unwind code entry gets a modifier of 1. Otherwise the modifier is 0.|
|.ENDPROLOG|Signals the end of the prologue declarations. Must occur in the first 255 bytes of the function.|
Here's a sample function prolog with proper usage of most of the opcodes:
@@ -384,19 +388,19 @@ For more information about the epilog example, see [Epilog code](prolog-and-epil
### MASM macros
-In order to simplify the use of the [Raw pseudo-operations](#raw-pseudo-operations), there's a set of macros, defined in ksamd64.inc, which can be used to create typical procedure prologues and epilogues.
+To simplify the use of [Raw pseudo-operations](#raw-pseudo-operations), use the set of macros defined in `ksamd64.inc`. These macros help you create typical procedure prologues and epilogues.
|Macro|Description|
|-|-|
-|alloc_stack(n)|Allocates a stack frame of n bytes (using `sub rsp, n`), and emits the appropriate unwind information (.allocstack n)|
-|save_reg *reg*, *loc*|Saves a nonvolatile register *reg* on the stack at RSP offset *loc*, and emits the appropriate unwind information. (.savereg reg, loc)|
-|push_reg *reg*|Pushes a nonvolatile register *reg* on the stack, and emits the appropriate unwind information. (.pushreg reg)|
-|rex_push_reg *reg*|Saves a nonvolatile register on the stack using a 2-byte push, and emits the appropriate unwind information (.pushreg reg). Use this macro if the push is the first instruction in the function, to ensure that the function is hot-patchable.|
-|save_xmm128 *reg*, *loc*|Saves a nonvolatile XMM register *reg* on the stack at RSP offset *loc*, and emits the appropriate unwind information (.savexmm128 reg, loc)|
-|set_frame *reg*, *offset*|Sets the frame register *reg* to be the RSP + *offset* (using a `mov`, or an `lea`), and emits the appropriate unwind information (.set_frame reg, offset)|
-|push_eflags|Pushes the eflags with a `pushfq` instruction, and emits the appropriate unwind information (.alloc_stack 8)|
-
-Here's a sample function prolog with proper usage of the macros:
+|alloc_stack(n)|Allocates a stack frame of *n* bytes (using `sub rsp, n`), and emits the appropriate unwind information (.allocstack n)|
+|save_reg *reg*, *loc*|Saves a nonvolatile register *reg* on the stack at `RSP` offset *loc*, and emits the appropriate unwind information (.savereg reg, loc)|
+|push_reg *reg*|Pushes a nonvolatile register *reg* on the stack, and emits the appropriate unwind information (.pushreg reg)|
+|rex_push_reg *reg*|Saves a nonvolatile register on the stack by using a 2-byte push, and emits the appropriate unwind information (.pushreg reg). Use this macro if the push is the first instruction in the function, to ensure that the function is hot-patchable.|
+|save_xmm128 *reg*, *loc*|Saves a nonvolatile `XMM` register *reg* on the stack at `RSP` offset *loc*, and emits the appropriate unwind information (.savexmm128 reg, loc)|
+|set_frame *reg*, *offset*|Sets the frame register *reg* to be the `RSP` + *offset* (using a `mov` or an `lea`), and emits the appropriate unwind information (.set_frame reg, offset)|
+|push_eflags|Pushes the eflags by using a `pushfq` instruction, and emits the appropriate unwind information (.alloc_stack 8)|
+
+Here's a sample function prologue with proper usage of the macros:
```MASM
sampleFrame struct
diff --git a/docs/build/how-to-create-a-release-build.md b/docs/build/how-to-create-a-release-build.md
index be26a6e5da9..9aec226e84f 100644
--- a/docs/build/how-to-create-a-release-build.md
+++ b/docs/build/how-to-create-a-release-build.md
@@ -1,18 +1,32 @@
---
-description: "Learn more about: How to: Create a Release Build"
title: "How to: Create a Release Build"
-ms.date: "11/04/2016"
+description: Learn how to create a release build in Visual Studio. Switch configurations, optimize your program, and prepare it for distribution.
+ms.date: "07/16/2026"
+author: TimShererWithAquent
+ms.author: v-tishe
helpviewer_keywords: ["Win32, release build", "release builds, creating"]
ms.assetid: 6a4c89b1-48f0-44d2-8703-ca0a4b0351bf
+#customer intent: As a developer, I want to create a release build of my program, so that I can distribute an optimized version to my users.
---
-# How to: Create a Release Build
+# How to create a release build
-### To generate a release build of your program
+Visual Studio projects have separate release and debug configurations for your program: debug version and release version for distribution.
-1. Select **Release** from the **Solution Configuration** drop-down list, which is on the **Standard** toolbar.
+In debug configuration, your program has symbolic debug information and no optimization. The release configuration of your program has no symbolic debug information and is fully optimized.
-1. On the **Build** menu, click **Build**.
+To generate a release build of your program, follow these steps:
+
+1. Open your solution in Visual Studio.
+1. In the **Solutions Configuration** menu under the toolbar, select **Release**.
+
+ :::image type="content" source="media/vs-2026/configure-release-build.png" alt-text="Screenshot shows Visual Studio Solutions Configuration menu with Release highlighted.":::
+
+1. From the **Build** menu, select **Build**.
+
+You can instead select **Configuration Manager**, where you can edit the build and release configurations. You can also create custom configurations to debug and release your program for different contexts and platforms.
## See also
-[Release Builds](release-builds.md)
+- [Project and solution configurations](/visualstudio/ide/understanding-build-configurations)
+- [Release Builds](release-builds.md)
+- [Common problems](common-problems-when-creating-a-release-build.md)
diff --git a/docs/build/how-to-enable-a-64-bit-visual-cpp-toolset-on-the-command-line.md b/docs/build/how-to-enable-a-64-bit-visual-cpp-toolset-on-the-command-line.md
index e551b430faf..0467db81855 100644
--- a/docs/build/how-to-enable-a-64-bit-visual-cpp-toolset-on-the-command-line.md
+++ b/docs/build/how-to-enable-a-64-bit-visual-cpp-toolset-on-the-command-line.md
@@ -1,36 +1,41 @@
---
-description: "Learn more about: How to: Enable a 64-Bit, x64 hosted MSVC toolset on the command line"
title: "How to: Enable a 64-Bit MSVC Toolset on the Command Line"
-ms.date: "07/24/2019"
+description: "Learn how to enable a 64-Bit, x64 hosted MSVC toolset on the command line. Use this toolset to create apps that run on 32-bit, 64-bit, or ARM-based systems."
+ms.date: "05/28/2026"
helpviewer_keywords: ["x64 [C++]", "64-bit compiler [C++], command line usage", "64-bit compiler [C++], toolset enabling at command line", "command line [C++], 64-bit compiler", "Itanium [C++], command-line compiler", "IPF", "Itanium [C++]", "IPF, command-line compiler", "x64 [C++], command-line compiler"]
+#customer intent: As a developer, I need the toolset installed with Visual Studio to build code for x86, x64, or ARM processors.
---
# How to: Enable a 64-Bit, x64 hosted MSVC toolset on the command line
-Visual Studio includes C++ compilers, linkers, and other tools that you can use to create platform-specific versions of your apps that can run on 32-bit, 64-bit, or ARM-based Windows operating systems. Other optional Visual Studio workloads let you use C++ tools to target other platforms, such as iOS, Android, and Linux. The default build architecture uses 32-bit, x86-hosted tools to build 32-bit, x86-native Windows code. However, you probably have a 64-bit computer. When Visual Studio is installed on a 64-bit Windows operating system, additional developer command prompt shortcuts for the 64-bit, x64-hosted native and cross compilers are available. You can take advantage of the processor and memory space available to 64-bit code by using the 64-bit, x64-hosted toolset when you build code for x86, x64, or ARM processors.
+Visual Studio includes C++ compilers, linkers, and other tools that you can use to create platform-specific versions of your apps. You can create versions that run on 32-bit, 64-bit, or ARM-based Windows operating systems. Other optional Visual Studio workloads let you use C++ tools to target other platforms, such as iOS, Android, and Linux. The default build architecture uses 32-bit, x86-hosted tools to build 32-bit, x86-native Windows code.
+
+You probably have a 64-bit computer. When Visual Studio is installed on a 64-bit Windows operating system, other developer command prompt shortcuts for the 64-bit, x64-hosted native, and cross compilers are available. You can take advantage of the processor and memory space available to 64-bit code by using the 64-bit, x64-hosted toolset when you build code for x86, x64, or ARM processors.
## Use a 64-bit hosted developer command prompt shortcut
-To access these command prompts on Windows, on the **Start** menu type `x64` and then choose one of the x64 native or cross-tool developer command prompts.
+To access these command prompts on Windows, on the **Start** menu, type `x64` and then choose one of the x64 native or cross-tool developer command prompts.
:::image type="complex" source="./media/x64-native-tools-command-prompt.png" alt-text="Screenshot showing the start menu with x64 in the search box and the x64 Native Tools Command Prompt shortcut selected.":::
If you have different versions of Visual Studio installed, other versions of the prompt appear. Choose the prompt for the version of Visual Studio that you want to use.
:::image-end:::
-On earlier versions of Windows, choose **Start**, expand **All Programs**, and then expand the folder for your version of **Visual Studio** (and on older versions of Visual Studio, **Visual Studio Tools**). For more information, see [Developer command prompt shortcuts](building-on-the-command-line.md#developer_command_prompt_shortcuts).
+On earlier versions of Windows, choose **Start**, expand **All Programs**, and then expand the folder for your version of **Visual Studio**. For older versions of Visual Studio, this folder is **Visual Studio Tools**. For more information, see [Developer command prompt shortcuts](building-on-the-command-line.md#developer_command_prompt_shortcuts).
-## Use Vcvarsall.bat to set a 64-bit hosted build architecture
+## Use vcvarsall.bat to set a 64-bit hosted build architecture
-Any of the native or cross compiler tools build configurations can be used on the command line by running the vcvarsall.bat command file. This command file configures the path and environment variables that enable a particular build architecture in an existing command prompt window. For specific instructions, see [Developer command file locations](building-on-the-command-line.md#developer_command_file_locations).
+Any of the native or cross compiler tools build configurations can be used on the command line by running the `vcvarsall.bat` command file. This command file configures the path and environment variables that enable a particular build architecture in an existing command prompt window. For more information, see [Developer command file locations](building-on-the-command-line.md#developer_command_file_locations).
## Remarks
+When you install a C++ workload in the Visual Studio installer, it always installs 32-bit, x86-hosted, native, and cross compiler tools to build x86 and x64 code. If you include the Universal Windows Platform workload, it also installs x86-hosted cross compiler tools to build ARM code.
+
+If you install these workloads on a 64-bit, x64 processor, you also get 64-bit native and cross compiler tools to build x86, x64, and ARM code. The 32-bit and 64-bit tools generate identical code, but the 64-bit tools support more memory for precompiled header symbols and the Whole Program Optimization ([/GL](reference/gl-whole-program-optimization.md) and [/LTCG](reference/ltcg-link-time-code-generation.md)) options. If you run into memory limits when you use the 32-bit tools, try the 64-bit tools.
+
> [!NOTE]
-> For information about the specific tools that are included with each Visual Studio edition, see [Visual C++ Tools and Features in Visual Studio Editions](../overview/visual-cpp-tools-and-features-in-visual-studio-editions.md).
+> For information about the specific tools that are included with each Visual Studio edition, see [C++ Tools and Features in Visual Studio Editions](../overview/visual-cpp-tools-and-features-in-visual-studio-editions.md).
>
-> For information about how to use the Visual Studio IDE to create 64-bit applications, see [How to: Configure Microsoft C++ Projects to Target 64-Bit, x64 Platforms](how-to-configure-visual-cpp-projects-to-target-64-bit-platforms.md).
-
-When you install a C++ workload in the Visual Studio installer, it always installs 32-bit, x86-hosted, native and cross compiler tools to build x86 and x64 code. If you include the Universal Windows Platform workload, it also installs x86-hosted cross compiler tools to build ARM code. If you install these workloads on a 64-bit, x64 processor, you also get 64-bit native and cross compiler tools to build x86, x64, and ARM code. The 32-bit and 64-bit tools generate identical code, but the 64-bit tools support more memory for precompiled header symbols and the Whole Program Optimization ([/GL](reference/gl-whole-program-optimization.md) and [/LTCG](reference/ltcg-link-time-code-generation.md)) options. If you run into memory limits when you use the 32-bit tools, try the 64-bit tools.
+> For information about how to use the Visual Studio IDE to create 64-bit applications, see [How to: Configure Visual Studio C++ Projects to Target 64-Bit, x64 Platforms](how-to-configure-visual-cpp-projects-to-target-64-bit-platforms.md).
## See also
-[Configure C++ projects for 64-bit, x64 targets](configuring-programs-for-64-bit-visual-cpp.md)
+- [Configure C++ projects for 64-bit, x64 targets](configuring-programs-for-64-bit-visual-cpp.md)
diff --git a/docs/build/launch-vs-schema-reference-cpp.md b/docs/build/launch-vs-schema-reference-cpp.md
index e7d4f24ef18..6313e0435a3 100644
--- a/docs/build/launch-vs-schema-reference-cpp.md
+++ b/docs/build/launch-vs-schema-reference-cpp.md
@@ -1,7 +1,7 @@
---
title: "launch.vs.json schema reference (C++)"
description: "Describes the schema elements for the `launch.vs.json` file"
-ms.date: 07/15/2021
+ms.date: 06/30/2026
helpviewer_keywords: ["launch.vs.json file [C++]"]
---
# `launch.vs.json` schema reference (C++)
@@ -40,6 +40,7 @@ To create the file, right-click on an executable file in **Solution Explorer** a
| `sourceFileMap` | object | Optional source file mappings passed to the debug engine. Format: `{ "\": "\" }` or `{ "\": { "editorPath": "\", "useForBreakpoints": true } }`. Example: `{ "/home/user/foo": "C:\\foo" }` or `{ "/home/user/foo": { "editorPath": "c:\\foo", "useForBreakpoints": true } }`. For more information, see [Source file map options](#source_file_map_options). |
| `additionalProperties` | string | One of the sourceFileMapOptions. (See below.) |
| `MIMode` | string | Indicates the type of MI-enabled console debugger that the MIDebugEngine will connect to. Allowed values are `"gdb"`, `"lldb"`. |
+| `debuginfod` | object | Controls how `gdb` uses [debuginfod](https://sourceware.org/elfutils/Debuginfod.html) to download missing debug symbols and source files from debuginfod servers. Visual Studio applies this option only when `MIMode` is `gdb`. For more information, see [debuginfod options](#debuginfod_options). |
| `args` | array | Command-line arguments passed to the program. |
| `environment` | array | Environment variables to add to the environment for the program. Example: `[ { "name": "squid", "value": "clam" } ]`. |
| `targetArchitecture` | string | The architecture of the debuggee. The architecture is detected automatically unless this parameter is set. Allowed values are `x86`, `arm`, `arm64`, `mips`, `x64`, `amd64`, `x86_64`. |
@@ -147,3 +148,21 @@ Use with the `sourceFileMap` property:
|--|--|--|
| `editorPath` | string | The location of the source code for the editor to locate. |
| `useForBreakpoints` | boolean | When setting breakpoints, this source mapping should be used. If **`false`**, only the filename and line number is used for setting breakpoints. If **`true`**, breakpoints will be set with the full path to the file and line number only when this source mapping is used. Otherwise just filename and line number will be used when setting breakpoints. Default is **`true`**. |
+
+## debuginfod options
+
+Use with the `debuginfod` property to control how `gdb` downloads debug symbols from debuginfod servers. On Linux systems that configure debuginfod, such as Ubuntu, Fedora, or Arch Linux, this option lets `gdb` automatically retrieve debug symbols and source files from the distribution's debuginfod servers so you don't have to install debug symbol packages manually. Visual Studio applies this option only when `MIMode` is `gdb`.
+
+| Property | Type | Description |
+|--|--|--|
+| `enabled` | boolean | When `true`, `gdb` queries debuginfod servers for missing debug info and source files. The default value is **`false`**, which avoids delays caused by network requests. |
+| `timeout` | integer | The timeout in seconds for debuginfod server requests. The default value is **`30`**. Set it to `0` to use `gdb`'s default timeout. |
+
+The following example enables debuginfod server support and sets the timeout to 10 seconds:
+
+```json
+"debuginfod": {
+ "enabled": true,
+ "timeout": 10
+}
+```
diff --git a/docs/build/media/add-new-project-property-sheet.png b/docs/build/media/add-new-project-property-sheet.png
new file mode 100644
index 00000000000..3241dc98580
Binary files /dev/null and b/docs/build/media/add-new-project-property-sheet.png differ
diff --git a/docs/build/media/github-copilot-fix-warning-accept.png b/docs/build/media/github-copilot-fix-warning-accept.png
deleted file mode 100644
index bb8f3ded876..00000000000
Binary files a/docs/build/media/github-copilot-fix-warning-accept.png and /dev/null differ
diff --git a/docs/build/media/github-copilot-fix-warning.png b/docs/build/media/github-copilot-fix-warning.png
deleted file mode 100644
index 4751bafdf01..00000000000
Binary files a/docs/build/media/github-copilot-fix-warning.png and /dev/null differ
diff --git a/docs/build/media/github-copilot-open-chat.png b/docs/build/media/github-copilot-open-chat.png
deleted file mode 100644
index c89019f9abc..00000000000
Binary files a/docs/build/media/github-copilot-open-chat.png and /dev/null differ
diff --git a/docs/build/media/normal-build-process.png b/docs/build/media/normal-build-process.png
new file mode 100644
index 00000000000..fbf6c0d1796
Binary files /dev/null and b/docs/build/media/normal-build-process.png differ
diff --git a/docs/build/media/sample-profile-guided-optimization-build-process.png b/docs/build/media/sample-profile-guided-optimization-build-process.png
new file mode 100644
index 00000000000..9de3effdc4b
Binary files /dev/null and b/docs/build/media/sample-profile-guided-optimization-build-process.png differ
diff --git a/docs/build/media/sharingnew.png b/docs/build/media/sharingnew.png
deleted file mode 100644
index 2316c884b97..00000000000
Binary files a/docs/build/media/sharingnew.png and /dev/null differ
diff --git a/docs/build/media/vs-2022/choose-console-app.png b/docs/build/media/vs-2022/choose-console-app.png
new file mode 100644
index 00000000000..067815d8e0f
Binary files /dev/null and b/docs/build/media/vs-2022/choose-console-app.png differ
diff --git a/docs/build/media/vs-2026/choose-console-app.png b/docs/build/media/vs-2026/choose-console-app.png
new file mode 100644
index 00000000000..934f106be49
Binary files /dev/null and b/docs/build/media/vs-2026/choose-console-app.png differ
diff --git a/docs/build/media/vs-2026/configure-release-build.png b/docs/build/media/vs-2026/configure-release-build.png
new file mode 100644
index 00000000000..a67c06c8fa3
Binary files /dev/null and b/docs/build/media/vs-2026/configure-release-build.png differ
diff --git a/docs/build/media/vs-2026/github-copilot-fix-warning-accept.png b/docs/build/media/vs-2026/github-copilot-fix-warning-accept.png
new file mode 100644
index 00000000000..06c1d036e2d
Binary files /dev/null and b/docs/build/media/vs-2026/github-copilot-fix-warning-accept.png differ
diff --git a/docs/build/media/vs-2026/github-copilot-fix-warning.png b/docs/build/media/vs-2026/github-copilot-fix-warning.png
new file mode 100644
index 00000000000..c5a5cbffd1f
Binary files /dev/null and b/docs/build/media/vs-2026/github-copilot-fix-warning.png differ
diff --git a/docs/build/media/vs-2026/github-copilot-open-chat.png b/docs/build/media/vs-2026/github-copilot-open-chat.png
new file mode 100644
index 00000000000..b7855f695d7
Binary files /dev/null and b/docs/build/media/vs-2026/github-copilot-open-chat.png differ
diff --git a/docs/build/media/vs-2026/output-error-list.png b/docs/build/media/vs-2026/output-error-list.png
new file mode 100644
index 00000000000..f75a320cd7c
Binary files /dev/null and b/docs/build/media/vs-2026/output-error-list.png differ
diff --git a/docs/build/media/vs-2026/solution-explorer.png b/docs/build/media/vs-2026/solution-explorer.png
new file mode 100644
index 00000000000..a6f561d740b
Binary files /dev/null and b/docs/build/media/vs-2026/solution-explorer.png differ
diff --git a/docs/build/media/vscpp-first-start-page-flag.png b/docs/build/media/vscpp-first-start-page-flag.png
deleted file mode 100644
index e17924233c7..00000000000
Binary files a/docs/build/media/vscpp-first-start-page-flag.png and /dev/null differ
diff --git a/docs/build/profile-guided-optimizations.md b/docs/build/profile-guided-optimizations.md
index 065565ef0d9..2da31ddff99 100644
--- a/docs/build/profile-guided-optimizations.md
+++ b/docs/build/profile-guided-optimizations.md
@@ -1,18 +1,20 @@
---
description: "Learn more about: Profile-guided optimizations"
title: "Profile-guided optimizations"
-ms.date: "04/23/2019"
+ms.date: 05/11/2026
helpviewer_keywords: ["profile-guided optimizations", "optimization, profile-guided [C++]"]
-ms.assetid: 2225c307-d3ae-42c1-8345-a5a959d132dc
---
# Profile-guided optimizations
-Profile-guided optimization (PGO) lets you optimize a whole executable file, where the optimizer uses data from test runs of the .exe or .dll file. The data represents the likely performance of the program in a production environment.
+Profile-guided optimization (PGO) lets you optimize a whole executable file. The optimizer uses data from test runs of the .exe or .dll file. The data represents the likely performance of the program in a production environment.
+
+> [!NOTE]
+> SPGO (Sample Profile-Guided Optimization) is an alternative approach that uses hardware CPU Windows Performance Counters instead of instrumentation. SPGO requires no instrumented build - you profile an existing release binary by using `xperf`. For more information, see [Introducing Sample Profile Guided Optimization in MSVC](https://devblogs.microsoft.com/cppblog/introducing-sample-profile-guided-optimization-in-msvc/) and [Sample Profile-Guided Optimization (SPGO) tutorial](sample-profile-guided-optimization.md).
Profile-guided optimizations are only available for x86, x64, or ARM64 native targets. Profile-guided optimizations aren't available for executable files that run on the common language runtime. Even if you produce an assembly with mixed native and managed code (by using the **/clr** compiler option), you can't use profile-guided optimization on just the native code. If you attempt to build a project with these options set in the IDE, a build error results.
> [!NOTE]
-> Information that's gathered from profiling test runs overrides optimizations that would otherwise be in effect if you specify **/Ob**, **/Os**, or **/Ot**. For more information, see [/Ob (Inline Function Expansion)](reference/ob-inline-function-expansion.md) and [/Os, /Ot (Favor Small Code, Favor Fast Code)](reference/os-ot-favor-small-code-favor-fast-code.md).
+> Information gathered from profiling test runs overrides optimizations that would otherwise be in effect if you specify **/Ob**, **/Os**, or **/Ot**. For more information, see [/Ob (Inline Function Expansion)](reference/ob-inline-function-expansion.md) and [/Os, /Ot (Favor Small Code, Favor Fast Code)](reference/os-ot-favor-small-code-favor-fast-code.md).
## Steps to optimize your app
@@ -20,36 +22,36 @@ To use profile-guided optimization, follow these steps to optimize your app:
- Compile one or more source code files with [/GL](reference/gl-whole-program-optimization.md).
- Each module built with **/GL** can be examined during profile-guided optimization test runs to capture run-time behavior. Every module in a profile-guided optimization build doesn't have to be compiled with **/GL**. However, only those modules compiled with **/GL** are instrumented and later available for profile-guided optimizations.
+ The compiler examines each module built with **/GL** during profile-guided optimization test runs to capture run-time behavior. You don't need to compile every module in a profile-guided optimization build with **/GL**. However, only modules compiled with **/GL** are instrumented and later available for profile-guided optimizations.
-- Link using [/LTCG](reference/ltcg-link-time-code-generation.md) and [/GENPROFILE or /FASTGENPROFILE](reference/genprofile-fastgenprofile-generate-profiling-instrumented-build.md).
+- Link by using [/LTCG](reference/ltcg-link-time-code-generation.md) and [/GENPROFILE or /FASTGENPROFILE](reference/genprofile-fastgenprofile-generate-profiling-instrumented-build.md).
- Using both **/LTCG** and **/GENPROFILE** or **/FASTGENPROFILE** creates a `.pgd` file when the instrumented app is run. After test-run data is added to the `.pgd` file, it can be used as input to the next link step (creating the optimized image). When specifying **/GENPROFILE**, you can optionally add a **PGD=**_filename_ argument to specify a nondefault name or location for the `.pgd` file. The combination of **/LTCG** and **/GENPROFILE** or **/FASTGENPROFILE** linker options replaces the deprecated **/LTCG:PGINSTRUMENT** linker option.
+ When you use both **/LTCG** and **/GENPROFILE** or **/FASTGENPROFILE**, the instrumented app creates a `.pgd` file when it runs. After test-run data is added to the `.pgd` file, you can use it as input to the next link step (creating the optimized image). When you specify **/GENPROFILE**, you can optionally add a **PGD=**_filename_ argument to specify a nondefault name or location for the `.pgd` file. The combination of **/LTCG** and **/GENPROFILE** or **/FASTGENPROFILE** linker options replaces the deprecated **/LTCG:PGINSTRUMENT** linker option.
- Profile the application.
- Each time a profiled EXE session ends, or a profiled DLL is unloaded, a `appname!N.pgc` file is created. A `.pgc` file contains information about a particular application test run. *appname* is the name of your app, and *N* is a number starting with 1 that's incremented based on the number of other `appname!N.pgc` files in the directory. You can delete a `.pgc` file if the test run doesn't represent a scenario you want to optimize.
+ Each time a profiled EXE session ends, or a profiled DLL unloads, the process creates an `appname!N.pgc` file. A `.pgc` file contains information about a particular application test run. *appname* is the name of your app, and *N* is a number starting with 1. It increments based on the number of other `appname!N.pgc` files in the directory. You can delete a `.pgc` file if the test run doesn't represent a scenario you want to optimize.
- During a test run, you can force closure of the currently open `.pgc` file and the creation of a new `.pgc` file with the [pgosweep](pgosweep.md) utility (for example, when the end of a test scenario doesn't coincide with application shutdown).
+ During a test run, you can force closure of the currently open `.pgc` file and the creation of a new `.pgc` file by using the [pgosweep](pgosweep.md) utility (for example, when the end of a test scenario doesn't coincide with application shutdown).
Your application can also directly invoke a PGO function, [PgoAutoSweep](pgoautosweep.md), to capture the profile data at the point of the call as a `.pgc` file. It can give you finer control over the code covered by the captured data in your `.pgc` files. For an example of how to use this function, see the [PgoAutoSweep](pgoautosweep.md) documentation.
When you create your instrumented build, by default, data collection is done in non-thread-safe mode, which is faster but may be imprecise. By using the **EXACT** argument to **/GENPROFILE** or **/FASTGENPROFILE**, you can specify data collection in thread-safe mode, which is more precise, but slower. This option is also available if you set the deprecated [PogoSafeMode](environment-variables-for-profile-guided-optimizations.md#pogosafemode) environment variable, or the deprecated **/POGOSAFEMODE** linker option, when you create your instrumented build.
-- Link using **/LTCG** and **/USEPROFILE**.
+- Link by using **/LTCG** and **/USEPROFILE**.
- Use both the **/LTCG** and [/USEPROFILE](reference/useprofile.md) linker options to create the optimized image. This step takes as input the `.pgd` file. When you specify **/USEPROFILE**, you can optionally add a **PGD=**_filename_ argument to specify a non-default name or location for the `.pgd` file. You can also specify this name by using the deprecated **/PGD** linker option. The combination of **/LTCG** and **/USEPROFILE** replaces the deprecated **/LTCG:PGOPTIMIZE** and **/LTCG:PGUPDATE** linker options.
+ Use both the **/LTCG** and [/USEPROFILE](reference/useprofile.md) linker options to create the optimized image. This step takes the `.pgd` file as input. When you specify **/USEPROFILE**, you can optionally add a **PGD=**_filename_ argument to specify a nondefault name or location for the `.pgd` file. You can also specify this name by using the deprecated **/PGD** linker option. The combination of **/LTCG** and **/USEPROFILE** linker options replaces the deprecated **/LTCG:PGOPTIMIZE** and **/LTCG:PGUPDATE** linker options.
-It's even possible to create the optimized executable file and later determine that additional profiling would be useful to create a more optimized image. If the instrumented image and its `.pgd` file are available, you can do additional test runs and rebuild the optimized image with the newer `.pgd` file, by using the same **/LTCG** and **/USEPROFILE** linker options.
+It's even possible to create the optimized executable file and later determine that more profiling would be useful to create a more optimized image. If the instrumented image and its `.pgd` file are available, you can do more test runs and rebuild the optimized image with the newer `.pgd` file by using the same **/LTCG** and **/USEPROFILE** linker options.
> [!NOTE]
-> Both `.pgc` and `.pgd` files are binary file types. If stored in a source control system, avoid any automatic transformation that may be made to text files.
+> Both `.pgc` and `.pgd` files are binary file types. If you store them in a source control system, avoid any automatic transformation that might be made to text files.
## Optimizations performed by PGO
-The profile-guided optimizations include these checks and improvements:
+Profile-guided optimizations include these checks and improvements:
-- **Inlining** - For example, if a function A frequently calls function B, and function B is relatively small, then profile-guided optimizations inline function B in function A.
+- **Inlining** - For example, if function A frequently calls function B, and function B is relatively small, the profile-guided optimizations inline function B in function A.
- **Virtual Call Speculation** - If a virtual call, or other call through a function pointer, frequently targets a certain function, a profile-guided optimization can insert a conditionally executed direct call to the frequently targeted function, and the direct call can be inlined.
@@ -61,33 +63,36 @@ The profile-guided optimizations include these checks and improvements:
- **Function Layout** - Based on the call graph and profiled caller/callee behavior, functions that tend to be along the same execution path are placed in the same section.
-- **Conditional Branch Optimization** - With the value probes, profile-guided optimizations can find if a given value in a switch statement is used more often than other values. This value can then be pulled out of the switch statement. The same can be done with **`if`**...**`else`** instructions where the optimizer can order the **`if`**...**`else`** so that either the **`if`** or **`else`** block is placed first, depending on which block is more frequently true.
+- **Conditional Branch Optimization** - With the value probes, profile-guided optimizations can find if a given value in a switch statement is used more often than other values. This value can then be pulled out of the switch statement. The same optimization can be done with **`if`**...**`else`** instructions where the optimizer can order the **`if`**...**`else`** so that either the **`if`** or **`else`** block is placed first, depending on which block is more frequently true.
-- **Dead Code Separation** - Code that isn't called during profiling is moved to a special section that's appended to the end of the set of sections. It effectively keeps this section out of the often-used pages.
+- **Dead Code Separation** - Profile-guided optimization moves code that isn't called during profiling to a special section at the end of the section set. It effectively keeps this section out of the often-used pages.
-- **EH Code Separation** - Because EH code is only exceptionally executed, it can often be moved to a separate section. It's moved when profile-guided optimizations can determine that the exceptions occur only on exceptional conditions.
+- **EH Code Separation** - Because EH code is only exceptionally executed, it can often be moved to a separate section. Profile-guided optimizations move it when they determine that the exceptions occur only on exceptional conditions.
-- **Memory Intrinsics** - Whether to expand an intrinsic or not depends on whether it's called frequently. An intrinsic can also be optimized based on the block size of moves or copies.
+- **Memory Intrinsics** - Whether to expand an intrinsic or not depends on whether it gets called frequently. An intrinsic can also be optimized based on the block size of moves or copies.
## Next steps
-Read more about these environment variables, functions, and tools you can use in profile-guided optimizations:
+To learn more about these environment variables, functions, and tools you can use in profile-guided optimizations, see the following resources:
-[Environment variables for profile-guided optimizations](environment-variables-for-profile-guided-optimizations.md)
-These variables were used to specify run-time behavior of testing scenarios. They're now deprecated and replaced by new linker options. This document shows you how to move from the environment variables to the linker options.
+[Environment variables for profile-guided optimizations](environment-variables-for-profile-guided-optimizations.md)\
+These variables specify the run-time behavior of testing scenarios. They're now deprecated and replaced by new linker options. This document shows you how to move from the environment variables to the linker options.
-[PgoAutoSweep](pgoautosweep.md)
+[PgoAutoSweep](pgoautosweep.md)\
A function you can add to your app to provide fine-grained `.pgc` file data capture control.
-[pgosweep](pgosweep.md)
+[pgosweep](pgosweep.md)\
A command-line utility that writes all profile data to the `.pgc` file, closes the `.pgc` file, and opens a new `.pgc` file.
-[pgomgr](pgomgr.md)
+[pgomgr](pgomgr.md)\
A command-line utility that adds profile data from one or more `.pgc` files to the `.pgd` file.
-[How to: Merge multiple PGO profiles into a single profile](how-to-merge-multiple-pgo-profiles-into-a-single-profile.md)
+[How to: Merge multiple PGO profiles into a single profile](how-to-merge-multiple-pgo-profiles-into-a-single-profile.md)\
Examples of **pgomgr** usage.
+[Sample Profile-Guided Optimization (SPGO) tutorial](sample-profile-guided-optimization.md)\
+Use CPU hardware performance counters instead of instrumentation. No instrumented build required - profile your existing release binary with `xperf`.
+
## See also
[Additional MSVC build tools](reference/c-cpp-build-tools.md)
diff --git a/docs/build/reference/arch-x64.md b/docs/build/reference/arch-x64.md
index 696f055f190..a48dc2984cc 100644
--- a/docs/build/reference/arch-x64.md
+++ b/docs/build/reference/arch-x64.md
@@ -7,7 +7,7 @@ helpviewer_keywords: ["/arch:SSE2 compiler option [C++]", "/arch:SSE4.2 compiler
---
# `/arch` (x64)
-Specifies the architecture for code generation on x64. These switches apply to the x64 targeting version of the compiler. For more information on **`/arch`** for other target architectures, see [`/arch` (x86)](arch-x86.md), [`/arch` (ARM64)](arch-arm64.md), and [`/arch` (ARM)](arch-arm.md).
+Specifies the architecture for code generation on x64. These switches apply to version of the compiler that targets x64. For more information about **`/arch`** for other target architectures, see [`/arch` (x86)](arch-x86.md), [`/arch` (ARM64)](arch-arm64.md), and [`/arch` (ARM)](arch-arm.md).
## Syntax
@@ -16,25 +16,25 @@ Specifies the architecture for code generation on x64. These switches apply to t
## Arguments
**`/arch:SSE2`**\
-Enables Intel Streaming SIMD Extensions 2. The default instruction set is SSE2 if no **`/arch`** option is specified.
+Enables x64 Streaming SIMD Extensions 2. If you don't specify a **`/arch`** option, the default instruction set is SSE2.
**`/arch:SSE4.2`**\
-Enables Intel Streaming SIMD Extensions 4.2.
+Enables x64 Streaming SIMD Extensions 4.2.
**`/arch:AVX`**\
-Enables Intel Advanced Vector Extensions.
+Enables x64 Advanced Vector Extensions.
**`/arch:AVX2`**\
-Enables Intel Advanced Vector Extensions 2.
+Enables x64 Advanced Vector Extensions 2.
**`/arch:AVX512`**\
-Enables Intel Advanced Vector Extensions 512.
+Enables x64 Advanced Vector Extensions 512.
**`/arch:AVX10.1`**\
-Enables Intel Advanced Vector Extensions 10 version 1.
+Enables x64 Advanced Vector Extensions 10 version 1.
**`/arch:AVX10.2`**\
-Enables Intel Advanced Vector Extensions 10 version 2.
+Enables x64 Advanced Vector Extensions 10 version 2.
## Remarks
@@ -84,5 +84,6 @@ Support for **`/arch:AVX10.1`** was added in Visual Studio 2022. Support for **`
## See also
[`/arch` (Minimum CPU Architecture)](arch-minimum-cpu-architecture.md)\
+[`/feature` (x64)](feature-x64.md)\
[MSVC compiler options](compiler-options.md)\
[MSVC compiler command-line syntax](compiler-command-line-syntax.md)
diff --git a/docs/build/reference/arch-x86.md b/docs/build/reference/arch-x86.md
index a133eda92db..411c90f5e4d 100644
--- a/docs/build/reference/arch-x86.md
+++ b/docs/build/reference/arch-x86.md
@@ -7,7 +7,7 @@ helpviewer_keywords: ["/arch:IA32 compiler option [C++]", "/arch:SSE compiler op
---
# `/arch` (x86)
-Specifies the architecture for code generation on x86. These switches apply to the x86 (32-bit) targeting version of the compiler. For more information on **`/arch`** for other target architectures, see [`/arch` (ARM64)](arch-arm64.md), [`/arch` (x64)](arch-x64.md), and [`/arch` (ARM)](arch-arm.md).
+Specifies the architecture for code generation on x86. These switches apply to the version of the compiler that targets x86 (32-bit). For more information about **`/arch`** for other target architectures, see [`/arch` (ARM64)](arch-arm64.md), [`/arch` (x64)](arch-x64.md), and [`/arch` (ARM)](arch-arm.md).
## Syntax
@@ -19,25 +19,25 @@ Specifies the architecture for code generation on x86. These switches apply to t
Specifies no enhanced instructions and also specifies x87 for floating-point calculations.
**`/arch:SSE`**\
-Enables Intel Streaming SIMD Extensions.
+Enables Streaming SIMD Extensions.
**`/arch:SSE2`**\
-Enables Intel Streaming SIMD Extensions 2. The default instruction set is SSE2 if no **`/arch`** option is specified.
+Enables Streaming SIMD Extensions 2. If you don't specify an **`/arch`** option, the default instruction set is SSE2.
**`/arch:AVX`**\
-Enables Intel Advanced Vector Extensions.
+Enables Advanced Vector Extensions.
**`/arch:AVX2`**\
-Enables Intel Advanced Vector Extensions 2.
+Enables Advanced Vector Extensions 2.
**`/arch:AVX512`**\
-Enables Intel Advanced Vector Extensions 512.
+Enables Advanced Vector Extensions 512.
**`/arch:AVX10.1`**\
-Enables Intel Advanced Vector Extensions 10 version 1.
+Enables Advanced Vector Extensions 10 version 1.
**`/arch:AVX10.2`**\
-Enables Intel Advanced Vector Extensions 10 version 2.
+Enables Advanced Vector Extensions 10 version 2.
## Remarks
diff --git a/docs/build/reference/common-macros-for-build-commands-and-properties.md b/docs/build/reference/common-macros-for-build-commands-and-properties.md
index bb52c1458b4..5f3cd0fc40d 100644
--- a/docs/build/reference/common-macros-for-build-commands-and-properties.md
+++ b/docs/build/reference/common-macros-for-build-commands-and-properties.md
@@ -59,8 +59,8 @@ This table describes a commonly used subset of the available macros; there are m
| **`$(TargetFileName)`** | The file name of the primary output file for the build (defined as base name + file extension). |
| **`$(TargetName)`** | The base name of the primary output file for the build. |
| **`$(TargetPath)`** | The absolute path name of the primary output file for the build (defined as drive + path + base name + file extension). |
-| **`$(VCInstallDir)`** | The directory that contains the C++ content of your Visual Studio installation. This property contains the version of the targeted Microsoft C++ (MSVC) toolset, which might be different that the host Visual Studio. For example, when building with `$(PlatformToolset) = v140`, **`$(VCInstallDir)`** contains the path to the Visual Studio 2015 installation. |
-| **`$(VSInstallDir)`** | The directory into which you installed Visual Studio. This property contains the version of the targeted Visual Studio toolset, which might be different that the host Visual Studio. For example, when building with `$(PlatformToolset) = v110`, **`$(VSInstallDir)`** contains the path to the Visual Studio 2012 installation. |
+| **`$(VCInstallDir)`** | The directory that contains the C++ content of your Visual Studio installation. This property contains the version of the targeted Microsoft C++ (MSVC) toolset, which might be different than the host Visual Studio. For example, when building with `$(PlatformToolset) = v140`, **`$(VCInstallDir)`** contains the path to the Visual Studio 2015 installation. |
+| **`$(VSInstallDir)`** | The directory into which you installed Visual Studio. This property contains the version of the targeted Visual Studio toolset, which might be different than the host Visual Studio. For example, when building with `$(PlatformToolset) = v110`, **`$(VSInstallDir)`** contains the path to the Visual Studio 2012 installation. |
| **`$(WebDeployPath)`** | The relative path from the web deployment root to where the project outputs belong. |
| **`$(WebDeployRoot)`** | The absolute path to the location of **``**. For example, *`c:\inetpub\wwwroot`*. |
diff --git a/docs/build/reference/compiler-options-listed-alphabetically.md b/docs/build/reference/compiler-options-listed-alphabetically.md
index 193a21544b1..8e2d8e81772 100644
--- a/docs/build/reference/compiler-options-listed-alphabetically.md
+++ b/docs/build/reference/compiler-options-listed-alphabetically.md
@@ -1,7 +1,8 @@
---
title: "Compiler options listed alphabetically"
description: "Reference listing in alphabetical order of the Microsoft C/C++ compiler command-line options."
-ms.date: 2/5/2025
+ms.date: 05/25/2026
+ai-usage: ai-assisted
helpviewer_keywords: ["compiler options, C++"]
---
# Compiler options listed alphabetically
@@ -66,7 +67,7 @@ This table contains an alphabetical list of compiler options. For a list of comp
| [`/FC`](fc-full-path-of-source-code-file-in-diagnostics.md) | Displays the full path of source code files passed to *cl.exe* in diagnostic text. |
| [`/Fd`](fd-program-database-file-name.md) | Renames program database file. |
| [`/Fe`](fe-name-exe-file.md) | Renames the executable file. |
-| [`/feature`](feature-arm64.md) | Enable architecture features.17.10 |
+| [`/feature`](feature-enable-architecture-features.md) | Enable architecture features. |
| [`/forceInterlockedFunctions`](force-interlocked-functions.md) | Dynamically selects between Armv8.0 load, store exclusive instructions or Armv8.1 LSE atomic instructions based on target CPU.17.14 |
| [`/FI`](fi-name-forced-include-file.md) | Preprocesses the specified include file. |
| [`/Fi`](fi-preprocess-output-file-name.md) | Specifies the preprocessed output file name. |
@@ -251,7 +252,7 @@ This table contains an alphabetical list of compiler options. For a list of comp
| [`/Zc:zeroSizeArrayNew[-]`](zc-zerosizearraynew.md) | Call member `new`/`delete` for zero-size arrays of objects (on by default). |
| [`/Ze`](za-ze-disable-language-extensions.md) | Deprecated. Enables C89 language extensions. |
| [`/Zf`](zf.md) | Improves PDB generation time in parallel builds. |
-| [`/ZH:[MD5|SHA1|SHA_256]`](zh.md) | Specifies MD5, SHA-1, or SHA-256 for checksums in debug info. |
+| [`/ZH:[MD5|SHA1|SHA_256|SHA384|SHA512]`](zh.md) | Specifies MD5, SHA-1, SHA-256, SHA-38418.6.0, or SHA-51218.6.0 for checksums in debug info. |
| [`/ZI`](z7-zi-zi-debug-information-format.md) | Includes debug information in a program database compatible with Edit and Continue. (x86 only) |
| [`/Zi`](z7-zi-zi-debug-information-format.md) | Generates complete debugging information. |
| [`/Zl`](zl-omit-default-library-name.md) | Removes the default library name from the *`.obj`* file. |
@@ -261,8 +262,8 @@ This table contains an alphabetical list of compiler options. For a list of comp
| [`/Zs`](zs-syntax-check-only.md) | Checks syntax only. |
| [`/ZW`](zw-windows-runtime-compilation.md) | Produces an output file to run on the Windows Runtime. |
-17.10 This option is available starting in Visual Studio 2022 version 17.10.\
-17.14 This option is available starting in Visual Studio 2022 version 17.14.
+17.14 This option is available starting in Visual Studio 2022 version 17.14.\
+18.6.0 This option is available starting in Visual Studio 2026 version 18.6.0 and MSVC version 14.51.
## See also
diff --git a/docs/build/reference/compiler-options-listed-by-category.md b/docs/build/reference/compiler-options-listed-by-category.md
index 5b2a78c030d..2636a52da0e 100644
--- a/docs/build/reference/compiler-options-listed-by-category.md
+++ b/docs/build/reference/compiler-options-listed-by-category.md
@@ -1,7 +1,8 @@
---
title: "Compiler Options Listed by Category"
description: "Reference listing by category of the Microsoft C/C++ compiler command-line options."
-ms.date: 2/5/2025
+ms.date: 05/25/2026
+ai-usage: ai-assisted
helpviewer_keywords: ["compiler options, C++"]
---
# Compiler options listed by category
@@ -43,7 +44,7 @@ This article contains a categorical list of compiler options. For an alphabetica
| [`/EHc`](eh-exception-handling-model.md) | `extern "C"` defaults to `nothrow`. |
| [`/EHr`](eh-exception-handling-model.md) | Always generate `noexcept` runtime termination checks. |
| [`/EHs`](eh-exception-handling-model.md) | Enable C++ exception handling (no SEH exceptions). |
-| [`/feature`](feature-arm64.md) | Enable architecture features.17.10 |
+| [`/feature`](feature-enable-architecture-features.md) | Enable architecture features. |
| [`/forceInterlockedFunctions`](force-interlocked-functions.md) | Dynamically selects between Armv8.0 load, store exclusive instructions or Armv8.1 LSE atomic instructions based on target CPU.17.14 |
| [`/fp:contract`](fp-specify-floating-point-behavior.md) | Consider floating-point contractions when generating code. |
| [`/fp:except[-]`](fp-specify-floating-point-behavior.md) | Consider floating-point exceptions when generating code. |
@@ -210,7 +211,7 @@ This article contains a categorical list of compiler options. For an alphabetica
| [`/Zc:zeroSizeArrayNew[-]`](zc-zerosizearraynew.md) | Call member `new`/`delete` for 0-size arrays of objects (on by default). |
| [`/Ze`](za-ze-disable-language-extensions.md) | Deprecated. Enables C89 language extensions. |
| [`/Zf`](zf.md) | Improves PDB generation time in parallel builds. |
-| [`/ZH`:[MD5|SHA1|SHA_256]](zh.md) | Specifies MD5, SHA-1, or SHA-256 for checksums in debug info. |
+| [`/ZH`:[MD5|SHA1|SHA_256|SHA384|SHA512]](zh.md) | Specifies MD5, SHA-1, SHA-256, SHA-38418.6.0, or SHA-51218.6.0 for checksums in debug info. |
| [`/ZI`](z7-zi-zi-debug-information-format.md) | Includes debug information in a program database compatible with Edit and Continue. (x86 only) |
| [`/Zi`](z7-zi-zi-debug-information-format.md) | Generates complete debugging information. |
| [`/Zl`](zl-omit-default-library-name.md) | Removes the default library name from the *`.obj`* file. |
@@ -219,6 +220,8 @@ This article contains a categorical list of compiler options. For an alphabetica
| [`/Zs`](zs-syntax-check-only.md) | Checks syntax only. |
| [`/ZW`](zw-windows-runtime-compilation.md) | Produces an output file to run on the Windows Runtime. |
+18.6.0 This option is available starting in Visual Studio 2026 version 18.6.0 and MSVC version 14.51.
+
## Linking
| Option | Purpose |
@@ -329,7 +332,6 @@ Experimental options may only be supported by certain versions of the compiler.
| [`/Ze`](za-ze-disable-language-extensions.md) | Deprecated. Enables language extensions. |
| [`/Zg`](zg-generate-function-prototypes.md) | Removed in Visual Studio 2015. Generates function prototypes. |
-17.10 This option is available starting in Visual Studio 2022 version 17.10.\
17.14 This option is available starting in Visual Studio 2022 version 17.14.
## See also
diff --git a/docs/build/reference/feature-arm64.md b/docs/build/reference/feature-arm64.md
index 2954b4fed11..b4a81178d93 100644
--- a/docs/build/reference/feature-arm64.md
+++ b/docs/build/reference/feature-arm64.md
@@ -16,6 +16,8 @@ To enable one or more features the targeted ARM64 extension supports, specify on
| Feature argument | Feature identifier | Optional from | Enabled by default | Description | Supported in version
|--|--|--|--|--|--|
+|**`cssc`** | `FEAT_CSSC` | Armv8.7 | Armv8.9 | Common Short Sequence Compression instructions. | Visual Studio 2026 18.10 (MSVC 14.52)
+|**`faminmax`** | `FEAT_FAMINMAX` | Armv9.2 | Armv9.5 | Floating-point maximum and minimum absolute value instructions. | Visual Studio 2026 18.10 (MSVC 14.52)
|**`lse`** | `FEAT_LSE` | Armv8.0 | Armv8.1 | Large System Extensions. | Visual Studio 2022 17.10
|**`rcpc`** | `FEAT_LRCPC` | Armv8.2 | Armv8.3 | Load-Acquire RCpc instructions. | Visual Studio 2022 17.10
|**`rcpc2`** | `FEAT_LRCPC2` | Armv8.2 | Armv8.4 | Load-Acquire RCpc instructions v2. | Visual Studio 2022 17.11
diff --git a/docs/build/reference/feature-enable-architecture-features.md b/docs/build/reference/feature-enable-architecture-features.md
new file mode 100644
index 00000000000..b9ca7324c68
--- /dev/null
+++ b/docs/build/reference/feature-enable-architecture-features.md
@@ -0,0 +1,23 @@
+---
+description: "Learn more about: /feature (Enable architecture features)"
+title: "/feature (Enable architecture features)"
+ms.date: 05/11/2026
+f1_keywords: ["/feature"]
+helpviewer_keywords: ["-feature compiler option [C++]", "/feature compiler option [C++]", "feature compiler option [C++]"]
+---
+# `/feature` (Enable architecture features)
+
+The **`/feature`** option enables specific architecture features for code generation. Select the target platform you're working with to see **`/feature`** options for that platform.
+
+- [`/feature` (ARM64)](feature-arm64.md)17.10
+
+- [`/feature` (x64)](feature-x64.md)14.51
+
+17.10 This option is available starting in Visual Studio 2022 version 17.10.\
+14.51 This option ships with MSVC Build Tools version 14.51. Available as part of Visual Studio starting with version 18.6.
+
+## See also
+
+[`/arch` (Minimum CPU architecture)](arch-minimum-cpu-architecture.md)\
+[MSVC compiler options](compiler-options.md)\
+[MSVC compiler command-line syntax](compiler-command-line-syntax.md)
diff --git a/docs/build/reference/feature-x64.md b/docs/build/reference/feature-x64.md
new file mode 100644
index 00000000000..676648ce4b5
--- /dev/null
+++ b/docs/build/reference/feature-x64.md
@@ -0,0 +1,57 @@
+---
+description: "Learn more about: /feature (x64)"
+title: "/feature (x64)"
+ms.date: 05/21/2026
+---
+# `/feature` (x64)
+
+Enable one or more architecture features for x64 code generation.
+
+> [!NOTE]
+> **`/feature:APX`** support is experimental and subject to change.
+
+## Syntax
+
+> **`/feature:`**
+
+## Arguments
+
+To enable one or more features the x64 target supports, specify one or more of the following feature arguments:
+
+| Feature argument | Description | Supported in version |
+|--|--|--|
+| **`APX`** | Enables preview support for Intel APX (Advanced Performance Extensions). Enables the compiler to target various APX features like Extended General-Purpose Registers (EGPRs), New Data Destination (NDD), No-Flags Update (NF), new conditional ISA and optimized registers save/restore operations. For more information, see [Intel Advanced Performance Extensions (APX)](https://www.intel.com/content/www/us/en/developer/articles/technical/advanced-performance-extensions-apx.html). | MSVC Build Tools 14.51 (Preview Support) |
+
+## Remarks
+
+Example usage: to enable APX, specify **`/feature:APX`**.
+
+When **`/feature:APX`** is specified, the following preprocessor macros are defined: `__APX_F__`, `__CCMP__`, `__CF__`, `__EGPR__`, `__NDD__`, `__NF__`, `__PPX__`, `__PUSH2POP2__`, and `__ZU__`. For more information, see [Microsoft-specific predefined macros](../../preprocessor/predefined-macros.md).
+
+APX extends the x64 architecture with new registers and instructions, which affects how the compiler generates calls, preserves state across function boundaries, and emits unwind metadata. The following articles describe the x64 conventions and unwind information related to APX:
+
+- [Caller/callee saved registers](../x64-calling-convention.md#callercallee-saved-registers)\
+ Describes which registers a callee must preserve and which the caller is responsible for saving across a call on x64.
+- [setjmp/longjmp](../x64-calling-convention.md#setjmplongjmp)\
+ Explains how nonlocal jumps capture and restore nonvolatile register state on x64, including the registers that participate in the jump buffer.
+- [Register volatility and preservation](../x64-software-conventions.md#register-volatility-and-preservation)\
+ Summarizes the x64 software conventions for volatile and nonvolatile general-purpose, `XMM`, `YMM`, and `ZMM` registers, and the rules callees must follow to preserve them.
+- [Exception handling unwind information V3](../x64-unwind-information-v3.md)\
+ Preview specification of the V3 unwind information format used to describe prologs, epilogs, and frame layout for x64 code, including the extended state introduced by APX.
+
+### To set the `/feature` compiler option in Visual Studio
+
+1. Open the **Property Pages** dialog box for the project. For more information, see [Set C++ compiler and build properties in Visual Studio](../working-with-project-properties.md).
+1. Select the **Configuration Properties** > **C/C++** > **Command Line** property page.
+1. In the **Additional options** box, add *`/feature:APX`*. Choose **OK** to save your changes.
+
+### To set this compiler option programmatically
+
+- See .
+
+## See also
+
+[`/arch` (x64)](arch-x64.md)\
+[`/arch` (Minimum CPU architecture)](arch-minimum-cpu-architecture.md)\
+[MSVC compiler options](compiler-options.md)\
+[MSVC compiler command-line syntax](compiler-command-line-syntax.md)
diff --git a/docs/build/reference/fsanitize.md b/docs/build/reference/fsanitize.md
index e1eef40728d..56a37b801fc 100644
--- a/docs/build/reference/fsanitize.md
+++ b/docs/build/reference/fsanitize.md
@@ -29,7 +29,9 @@ The **`/fsanitize=fuzzer`** compiler option enables experimental support for [Li
The **`/fsanitize`** option doesn't allow comma-separated syntax, for example: **`/fsanitize=address,fuzzer`**. These options must be specified individually.
-The **`/fsanitize-address-use-after-return`**, **`/fno-sanitize-address-vcasan-lib`**, **`/fsanitize-address-asan-compat-lib`**, and **`/fno-sanitize-address-asan-compat-lib`** compiler options, and the [`/INFERASANLIBS` (Use inferred sanitizer libs)](./inferasanlibs.md) and **`/INFERASANLIBS:NO`** linker options offer support for advanced users. For more information, see [AddressSanitizer build and language reference](../../sanitizers/asan-building.md).
+The **`/fsanitize-address-use-after-return`** compiler option enables experimental support for detecting memory safety issues arising from using a variable that has left scope. This requires that the ASan runtime option `ASAN_OPTIONS=detect_stack_use_after_return=1` is also set and incurs an additional performance penalty. For more information, see [Error: stack-use-after-return](../../sanitizers/error-stack-use-after-return.md).
+
+The **`/fno-sanitize-address-vcasan-lib`**, **`/fsanitize-address-asan-compat-lib`**, and **`/fno-sanitize-address-asan-compat-lib`** compiler options, and the [`/INFERASANLIBS` (Use inferred sanitizer libs)](./inferasanlibs.md) and **`/INFERASANLIBS:NO`** linker options offer support for advanced users. For more information, see [AddressSanitizer build and language reference](../../sanitizers/asan-building.md).
### To set the **`/fsanitize=address`** compiler option in the Visual Studio development environment
diff --git a/docs/build/reference/internal-partition.md b/docs/build/reference/internal-partition.md
index 393c44956ac..9a91b9ebb7b 100644
--- a/docs/build/reference/internal-partition.md
+++ b/docs/build/reference/internal-partition.md
@@ -1,7 +1,7 @@
---
title: "/internalPartition"
description: "Use the /internalPartition compiler option to treat the input file as an internal partition unit."
-ms.date: 11/16/2022
+ms.date: 6/3/2026
author: "tylermsft"
ms.author: "twhitney"
f1_keywords: ["/internalPartition", "VC.Project.VCCLCompilerTool.Interface"]
@@ -52,7 +52,7 @@ This option can't be used with the [`/interface`](interface.md) compiler option.
### To set this compiler option in the Visual Studio development environment
-You normally shouldn't set this option in the Visual Studio development environment unless you use a different extension for your partition files. By default, the build system applies this option to files that have a *`.ixx`** extension.
+You normally shouldn't set this option in the Visual Studio development environment unless you use a different extension for your partition files. By default, the build system applies this option to files that have a *`.ixx`* extension.
1. To apply the **`/internalPartition`** option to a file explicitly in the IDE, select the file in **Solution Explorer**. Right-click to open the context menu and select **Properties** to open the Property Pages dialog.
@@ -66,4 +66,4 @@ You normally shouldn't set this option in the Visual Studio development environm
[Overview of modules in C++](../../cpp/modules-cpp.md)\
[Using C++ Modules in MSVC from the Command Line](https://devblogs.microsoft.com/cppblog/using-cpp-modules-in-msvc-from-the-command-line-part-1/)\
-[C++ Modules conformance improvements with MSVC in Visual Studio 2019 16.5](https://devblogs.microsoft.com/cppblog/c-modules-conformance-improvements-with-msvc-in-visual-studio-2019-16-5/#module-partitions)
\ No newline at end of file
+[C++ Modules conformance improvements with MSVC in Visual Studio 2019 16.5](https://devblogs.microsoft.com/cppblog/c-modules-conformance-improvements-with-msvc-in-visual-studio-2019-16-5/#module-partitions)
diff --git a/docs/build/reference/linker-options.md b/docs/build/reference/linker-options.md
index 5749d0c2364..a647917101a 100644
--- a/docs/build/reference/linker-options.md
+++ b/docs/build/reference/linker-options.md
@@ -7,7 +7,7 @@ helpviewer_keywords: ["linker [C++]", "linker [C++], options listed", "libraries
---
# Linker options
-LINK.exe links Common Object File Format (COFF) object files and libraries to create an executable (EXE) file or a dynamic-link library (DLL).
+`LINK.exe` links Common Object File Format (COFF) object files and libraries to create an executable (EXE) file or a dynamic-link library (DLL).
The following table lists options for `LINK.exe`. For more information about LINK, see:
@@ -16,9 +16,9 @@ The following table lists options for `LINK.exe`. For more information about LIN
- [LINK output](link-output.md)
- [Reserved words](reserved-words.md)
-Linker options aren't case-sensitive; for example, `/base` and `/BASE` mean the same thing. For details on how to specify each option on the command line or in Visual Studio, see the documentation for that option.
+Linker options aren't case-sensitive. For example, `/base` and `/BASE` mean the same thing. For details on how to specify each option on the command line or in Visual Studio, see the documentation for that option.
-You can use the [`comment`](../../preprocessor/comment-c-cpp.md) pragma to specify some linker options.
+Use the [`comment`](../../preprocessor/comment-c-cpp.md) pragma to specify some linker options.
## Linker options listed alphabetically
@@ -112,6 +112,10 @@ You can use the [`comment`](../../preprocessor/comment-c-cpp.md) pragma to speci
| [`/SAFESEH`](safeseh-image-has-safe-exception-handlers.md) | Specifies that the image will contain a table of safe exception handlers. |
| [`/SECTION`](section-specify-section-attributes.md) | Overrides the attributes of a section. |
| [`/SOURCELINK`](sourcelink.md) | Specifies a SourceLink file to add to the PDB. |
+| [`/SPD`](spd-specify-sample-profile-database.md) | Specifies the name and location of the *`.spd`* file for Sample Profile-Guided Optimization. |
+| [`/SPDEMBED`](spdembed-embed-sample-profile-database.md) | Embeds the Sample Profile Database into the PDB file during a Sample Profile-Guided Optimization (SPGO) build. |
+| [`/SPDIN`](spdin-use-sample-profile-database.md) | Specifies a *`.spd`* file containing profiling data for an optimized Sample Profile-Guided Optimization (SPGO) build. |
+| [`/SPGO`](spgo-enable-sample-profile-guided-optimization.md) | Enables Sample Profile-Guided Optimization and creates an empty *`.spd`* file. |
| [`/STACK`](stack-stack-allocations.md) | Sets the size of the stack in bytes. |
| [`/STUB`](stub-ms-dos-stub-file-name.md) | Attaches an MS-DOS stub program to a Win32 program. |
| [`/SUBSYSTEM`](subsystem-specify-subsystem.md) | Tells the operating system how to run the *`.exe`* file. |
diff --git a/docs/build/reference/manifest-tool-property-pages.md b/docs/build/reference/manifest-tool-property-pages.md
index cdf705d3d85..fc70cc16669 100644
--- a/docs/build/reference/manifest-tool-property-pages.md
+++ b/docs/build/reference/manifest-tool-property-pages.md
@@ -22,6 +22,7 @@ f1_keywords:
- VC.Project.VCManifestTool.ReplacementsFile
- VC.Project.VCManifestTool.UpdateFileHashes
- VC.Project.VCManifestTool.UpdateFileHashesSearchPath
+ - VC.Project.VCManifestTool.EnableSegmentHeap
---
# Manifest Tool Property Pages
@@ -97,6 +98,10 @@ Specifies whether the application is DPI-aware. By default, the setting is **Yes
- **High DPI Aware**
- **Per Monitor High DPI Aware**
+### Segment Heap
+
+Specifies whether the application utilizes the Segment Heap. When enabled, applications benefit from improved memory efficiency, reduced fragmentation, and enhanced memory security. For new C++ projects, the setting is **Yes** by default.
+
## Isolated COM Property Page
For more information about isolated COM, see [Isolated applications](/windows/win32/SbsCs/isolated-applications) and [How to: Build isolated applications to consume COM components](../how-to-build-isolated-applications-to-consume-com-components.md).
diff --git a/docs/build/reference/spd-specify-sample-profile-database.md b/docs/build/reference/spd-specify-sample-profile-database.md
new file mode 100644
index 00000000000..f6afb2d2407
--- /dev/null
+++ b/docs/build/reference/spd-specify-sample-profile-database.md
@@ -0,0 +1,46 @@
+---
+title: "/SPD (Specify Sample Profile Database)"
+description: "Learn more about: /SPD (Specify Sample Profile Database)"
+ms.date: 05/05/2026
+ai-usage: ai-assisted
+helpviewer_keywords: ["/SPD linker option", "-SPD linker option", "sample profile-guided optimization, /SPD"]
+---
+# /SPD (Specify Sample Profile Database)
+
+Specifies the name and location of the Sample Profile Database (SPD) file used by the Sample Profile-Guided Optimization (SPGO) workflow.
+
+## Syntax
+
+> **/SPD:**_filename_
+
+## Argument
+
+`filename`\
+Specifies the name of the `.spd` file. When expanded, the fully qualified path must not exceed `MAX_PATH` (260 characters).
+
+## Remarks
+
+When you build with [`/SPGO`](spgo-enable-sample-profile-guided-optimization.md), the linker creates an empty SPD file alongside the output binary. By default, the SPD file uses the same base name as the output file and is created in the directory where you invoked the link. Use `/SPD` to specify a different name or path.
+
+When linking with [`/SPDIN`](spdin-use-sample-profile-database.md), use `/SPDIN` to specify the input SPD file and `/SPD` to specify the output SPD file.
+
+For more information about the SPGO workflow, see [Tutorial: Use Sample Profile-Guided Optimization (SPGO) to improve performance](../sample-profile-guided-optimization.md).
+
+### To set this linker option in the Visual Studio development environment
+
+1. Open the project's **Property Pages** dialog box. For details, see [Set C++ compiler and build properties in Visual Studio](../working-with-project-properties.md).
+1. Select the **Configuration Properties** > **Linker** > **Command Line** property page.
+1. Add `/SPD:filename` to the **Additional Options** box. Choose **OK** to save your changes.
+
+### To set this linker option programmatically
+
+- See .
+
+## See also
+
+[MSVC linker reference](linking.md)\
+[MSVC Linker Options](linker-options.md)\
+[/SPDEMBED (Embed Sample Profile Database)](spdembed-embed-sample-profile-database.md)\
+[/SPDIN (Use Sample Profile Database)](spdin-use-sample-profile-database.md)\
+[/SPGO (Enable Sample Profile-Guided Optimization)](spgo-enable-sample-profile-guided-optimization.md)\
+[Tutorial: Use Sample Profile-Guided Optimization (SPGO) to improve performance](../sample-profile-guided-optimization.md)
\ No newline at end of file
diff --git a/docs/build/reference/spdembed-embed-sample-profile-database.md b/docs/build/reference/spdembed-embed-sample-profile-database.md
new file mode 100644
index 00000000000..db91e8359f1
--- /dev/null
+++ b/docs/build/reference/spdembed-embed-sample-profile-database.md
@@ -0,0 +1,41 @@
+---
+title: "/SPDEMBED (Embed Sample Profile Database)"
+description: "Learn more about: /SPDEMBED (Embed Sample Profile Database)"
+ms.date: 05/05/2026
+ai-usage: ai-assisted
+helpviewer_keywords: ["/SPDEMBED linker option", "-SPDEMBED linker option", "sample profile-guided optimization, /SPDEMBED"]
+---
+# /SPDEMBED (Embed Sample Profile Database)
+
+Embeds the Sample Profile Database (SPD) data into the Program Database (PDB) file during a Sample Profile-Guided Optimization (SPGO) build.
+
+## Syntax
+
+> **/SPDEMBED**
+
+## Remarks
+
+When you build with [`/SPDIN`](spdin-use-sample-profile-database.md), the linker uses the profile data in the SPD file to make optimization decisions. Use `/SPDEMBED` together with `/SPGO` to embed the SPD data into the PDB file produced by the build. Embedding the SPD in the PDB keeps the profile data together with the debug symbols, which simplifies distribution and archiving of build artifacts.
+
+To extract an SPD file that you embedded in a PDB, use [`SPDConvert /extract`](../spdconvert.md).
+
+For more information about the SPGO workflow, see [Tutorial: Use Sample Profile-Guided Optimization (SPGO) to improve performance](../sample-profile-guided-optimization.md).
+
+### To set this linker option in the Visual Studio development environment
+
+1. Open the project's **Property Pages** dialog box. For details, see [Set C++ compiler and build properties in Visual Studio](../working-with-project-properties.md).
+1. Select the **Configuration Properties** > **Linker** > **Command Line** property page.
+1. Add `/SPDEMBED` to the **Additional Options** box. Choose **OK** to save your changes.
+
+### To set this linker option programmatically
+
+- See .
+
+## See also
+
+[MSVC linker reference](linking.md)\
+[MSVC Linker Options](linker-options.md)\
+[/SPD (Specify Sample Profile Database)](spd-specify-sample-profile-database.md)\
+[/SPDIN (Use Sample Profile Database)](spdin-use-sample-profile-database.md)\
+[/SPGO (Enable Sample Profile-Guided Optimization)](spgo-enable-sample-profile-guided-optimization.md)\
+[Tutorial: Use Sample Profile-Guided Optimization (SPGO) to improve performance](../sample-profile-guided-optimization.md)
\ No newline at end of file
diff --git a/docs/build/reference/spdin-use-sample-profile-database.md b/docs/build/reference/spdin-use-sample-profile-database.md
new file mode 100644
index 00000000000..b8ba7989923
--- /dev/null
+++ b/docs/build/reference/spdin-use-sample-profile-database.md
@@ -0,0 +1,52 @@
+---
+title: "/SPDIN (Use Sample Profile Database)"
+description: "Learn more about linker option: /SPDIN (Use Sample Profile Database)"
+ms.date: 05/05/2026
+ai-usage: ai-assisted
+helpviewer_keywords: ["/SPDIN linker option", "-SPDIN linker option", "sample profile-guided optimization, /SPDIN"]
+---
+# /SPDIN (Use Sample Profile Database)
+
+Specifies a Sample Profile Database (SPD) file that contains profiling data for use in a Sample Profile-Guided Optimization (SPGO) build.
+Also used to override the default or file specified with `/SPD` for reading the sample profile database.
+
+## Syntax
+
+> **/SPDIN:**_filename_
+
+## Argument
+
+`filename`\
+Specifies the path to the `.spd` file that contains the profiling data to use for optimization. When expanded, the fully qualified path must not exceed `MAX_PATH` (260 characters).\
+If the file doesn't exist, the linker creates an empty file that will be used to collect data.
+
+## Remarks
+
+After collecting a performance trace by using `xperf`, converting it by using [`SPTAggregate`](../sptaggregate.md), and importing the data into an SPD file by using [`SPDConvert`](../spdconvert.md), use `/SPDIN` and [`/SPGO`](spgo-enable-sample-profile-guided-optimization.md) to produce an optimized binary.
+
+The GUID and age of the binary recorded in the SPD file must match the SPT file. If they don't match, you may see a "SPD version incompatible" error. To diagnose this error, use [`SPTDump /progid`](../sptdump.md) to inspect the binary identifiers in the SPT file, and [`SPDDump /header`](../spddump.md) to inspect the SPD file. The linker uses a valid SPD file to the extent possible. Minor updates to the code that don't alter the program's control flow are tolerated. Unchanged functions also use the data for optimization. If you provide a valid, but otherwise unrelated SPD, the process works, but likely no data is usable for optimization.
+
+Use [`/SPDEMBED`](spdembed-embed-sample-profile-database.md) together with `/SPGO` to embed the SPD data into the PDB file produced by the build.
+
+Use [`/SPD`](spd-specify-sample-profile-database.md) to specify a nondefault name or location for the SPD file. `/SPDIN` overrides this option, if specified.
+
+For more information about the SPGO workflow, see [Tutorial: Use Sample Profile-Guided Optimization (SPGO) to improve performance](../sample-profile-guided-optimization.md).
+
+### To set this linker option in the Visual Studio development environment
+
+1. Open the project's **Property Pages** dialog box. For details, see [Set C++ compiler and build properties in Visual Studio](../working-with-project-properties.md).
+1. Select the **Configuration Properties** > **Linker** > **Command Line** property page.
+1. Add `/SPDIN:filename` to the **Additional Options** box. Choose **OK** to save your changes.
+
+### To set this linker option programmatically
+
+- See .
+
+## See also
+
+[MSVC linker reference](linking.md)\
+[MSVC Linker Options](linker-options.md)\
+[/SPD (Specify Sample Profile Database)](spd-specify-sample-profile-database.md)\
+[/SPDEMBED (Embed Sample Profile Database)](spdembed-embed-sample-profile-database.md)\
+[/SPGO (Enable Sample Profile-Guided Optimization)](spgo-enable-sample-profile-guided-optimization.md)\
+[Tutorial: Use Sample Profile-Guided Optimization (SPGO) to improve performance](../sample-profile-guided-optimization.md)
\ No newline at end of file
diff --git a/docs/build/reference/spgo-enable-sample-profile-guided-optimization.md b/docs/build/reference/spgo-enable-sample-profile-guided-optimization.md
new file mode 100644
index 00000000000..e2eeaa48ed2
--- /dev/null
+++ b/docs/build/reference/spgo-enable-sample-profile-guided-optimization.md
@@ -0,0 +1,51 @@
+---
+title: "/SPGO (Enable Sample Profile-Guided Optimization)"
+description: "Learn more about: /SPGO (Enable Sample Profile-Guided Optimization)"
+ms.date: 05/05/2026
+ai-usage: ai-assisted
+helpviewer_keywords: ["/SPGO linker option", "-SPGO linker option", "sample profile-guided optimization, /SPGO"]
+---
+# /SPGO (Enable Sample Profile-Guided Optimization)
+
+Enables Sample Profile-Guided Optimization (SPGO) and creates an empty Sample Profile Database (SPD) file alongside the output binary.
+
+## Syntax
+
+> **/SPGO**
+
+## Remarks
+
+The `/SPGO` linker option starts the SPGO workflow. It directs the linker to create an empty `.spd` file that acts as a placeholder for profiling data. After building with `/SPGO`, you collect a performance trace by using `xperf`, convert it to an SPT file by using [`SPTAggregate`](../sptaggregate.md), and then import the data into the SPD file by using [`SPDConvert`](../spdconvert.md). Once the SPD file contains profile data, rebuild by using the SPD file to produce an optimized binary. The compiler and linker look for an SPD input file, either default or specified by [`/SPD`](spd-specify-sample-profile-database.md). The [/SPDIN (Use Sample Profile Database)](spdin-use-sample-profile-database.md) option is available as a convenience when the input file is over-written and that isn't desirable.
+
+When you build by using `/SPGO` but the SPD file contains no profile data yet, you see a message such as:
+
+```
+Result: SPD .spd does not contain sample profile, compiling without profile guided optimizations
+```
+
+This message is expected on the first build and indicates that the SPD file is ready to receive profiling data.
+
+By default, the build process creates the SPD file with the same base name as the output file in the directory from which the link was invoked. Use [`/SPD`](spd-specify-sample-profile-database.md) to specify a different name or location.
+
+Use [`/SPDEMBED`](spdembed-embed-sample-profile-database.md) to embed the SPD data into the PDB file after profile data is collected. Ensure that the linker is producing a PDB file by specifying the `/DEBUG` option.
+
+For more information about the SPGO workflow, see [Tutorial: Use Sample Profile-Guided Optimization (SPGO) to improve performance](../sample-profile-guided-optimization.md).
+
+### To set this linker option in the Visual Studio development environment
+
+1. Open the project's **Property Pages** dialog box. For details, see [Set C++ compiler and build properties in Visual Studio](../working-with-project-properties.md).
+1. Select the **Configuration Properties** > **Linker** > **Command Line** property page.
+1. Add `/SPGO` to the **Additional Options** box. Choose **OK** to save your changes.
+
+### To set this linker option programmatically
+
+- See .
+
+## See also
+
+[MSVC linker reference](linking.md)\
+[MSVC Linker Options](linker-options.md)\
+[/SPD (Specify Sample Profile Database)](spd-specify-sample-profile-database.md)\
+[/SPDEMBED (Embed Sample Profile Database)](spdembed-embed-sample-profile-database.md)\
+[/SPDIN (Use Sample Profile Database)](spdin-use-sample-profile-database.md)\
+[Tutorial: Use Sample Profile-Guided Optimization (SPGO) to improve performance](../sample-profile-guided-optimization.md)
\ No newline at end of file
diff --git a/docs/build/reference/volatile.md b/docs/build/reference/volatile.md
index fb3cced8479..4f133333193 100644
--- a/docs/build/reference/volatile.md
+++ b/docs/build/reference/volatile.md
@@ -1,13 +1,13 @@
---
description: "Learn more about: /volatileMetadata"
title: "/volatileMetadata (Generate metadata on volatile memory accesses)"
-ms.date: 5/30/2024
+ms.date: 04/27/2026
f1_keywords: ["/volatileMetadata"]
helpviewer_keywords: ["/volatileMetadata", "-volatileMetadata compiler option", "/volatileMetadata compiler option", "volatileMetadata"]
---
# `/volatileMetadata` (Generate metadata on volatile memory accesses)
-Generate metadata for volatile memory accesses to improve performance when running x64 code on ARM64.
+Generate metadata for volatile memory accesses to improve performance when running x64 or x86 code on ARM64.
## Syntax
@@ -15,20 +15,14 @@ Generate metadata for volatile memory accesses to improve performance when runni
/volatileMetadata[-]
```
-## Arguments
-
-**`-`**\
-Turns off `/volatileMetadata`. This may result in worse performance when your code runs in emulation mode on ARM64 because the emulator pessimistically assumes that every load/store needs a barrier.
-
## Remarks
-Starting with Visual Studio 2019 16.10, `/volatileMetadata` is on by default when generating x64 code. It improves the emulation performance of x64 code on ARM64 by generating metadata that identifies volatile memory addresses. An emulator can use this metadata to improve performance by not using acquire/release semantics on those accesses it knows aren't volatile. Without this metadata, the emulator assumes that all addresses are volatile and uses acquire and release semantics.
+Starting with Visual Studio 2022 18.6, `/volatileMetadata` is off by default and must be explicitly enabled. To explicitly disable it, use `/volatileMetadata-`. `/volatileMetadata` improves the emulation performance of x64 and x86 code on ARM64 by generating metadata that identifies volatile memory addresses. An emulator can use this metadata to improve performance by not using acquire/release semantics on those accesses it knows aren't volatile. Without this metadata, the emulator assumes that all addresses are volatile and uses acquire and release semantics.
One side effect of `/volatileMetadata` is you may see `npad` macros used in the generated code. This macro expands to a specified number of `NOP` instructions that create an address to associate with a memory barrier. That address is then recorded in the metadata to indicate that acquire/release semantics should be used to access it.
-`/volatileMetadata` is ignored when targeting x86.
-
-`/volatileMetadata` can be disabled by using `/volatileMetadata-`.
+> [!NOTE]
+> In Visual Studio 2019 version 16.10 through Visual Studio 2022, `/volatileMetadata` was on by default. Starting with Visual Studio 2022 18.6, `/volatileMetadata` is off by default.
## Requirements
diff --git a/docs/build/reference/zc-conformance.md b/docs/build/reference/zc-conformance.md
index 77534192bb9..b2d72372b20 100644
--- a/docs/build/reference/zc-conformance.md
+++ b/docs/build/reference/zc-conformance.md
@@ -16,7 +16,7 @@ You may set multiple **`/Zc`** options separated by commas in a single **`/Zc`**
## Remarks
-When Visual Studio has implemented an extension to C or C++ that is incompatible with the standard, you can use a **`/Zc`** conformance option to specify standard-conforming or Microsoft-specific behavior. For some options, the Microsoft-specific behavior is the default, to prevent large-scale breaking changes to existing code. In other cases, the default is the standard behavior, where improvements in security, performance, or compatibility outweigh the costs of breaking changes. The default setting of each conformance option may change in newer versions of Visual Studio. For more information about each conformance option, see the article for the specific option. The [`/permissive-`](permissive-standards-conformance.md) compiler option implicitly sets the conformance options that aren't set by default to their conforming settings.
+When Visual Studio implements an extension to C or C++ that's incompatible with the standard, you can use a **`/Zc`** conformance option to specify standard-conforming or Microsoft-specific behavior. For some options, the Microsoft-specific behavior is the default, to prevent large-scale breaking changes to existing code. In other cases, the default is the standard behavior, where improvements in security, performance, or compatibility outweigh the costs of breaking changes. The default setting of each conformance option may change in newer versions of Visual Studio. For more information about each conformance option, see the article for the specific option. The [`/permissive-`](permissive-standards-conformance.md) compiler option implicitly sets the conformance options that aren't set by default to their conforming settings.
Here are the **`/Zc`** compiler options:
@@ -27,7 +27,7 @@ Here are the **`/Zc`** compiler options:
| [`/Zc:alignedNew[-]`](zc-alignednew.md) | Enable C++17 over-aligned dynamic allocation. Off by default unless **`/std:c++17`** or later is specified. |
| [`/Zc:auto[-]`](zc-auto-deduce-variable-type.md) | Enforce the new Standard C++ meaning for **`auto`**. On by default. |
| [`/Zc:char8_t[-]`](zc-char8-t.md) | Enable or disable C++20 native `u8` literal support as `const char8_t`. Off by default unless **`/std:c++20`** or later is specified. |
-| [`/Zc:checkGwOdr[-]`](zc-check-gwodr.md) | Enforce Standard C++ ODR violations under `/Gw`. |
+| [`/Zc:checkGwOdr[-]`](zc-check-gwodr.md) | Enforce Standard C++ One-Definition-Rule (ODR) violations under `/Gw`. |
| [`/Zc:enumTypes[-]`](zc-enumtypes.md) | Enable Standard C++ rules for `enum` type deduction. Off by default. |
| [`/Zc:externC[-]`](zc-externc.md) | Enforce Standard C++ rules for `extern "C"` functions. Off by default unless **`/permissive-`** is specified. |
| [`/Zc:externConstexpr[-]`](zc-externconstexpr.md) | Enable external linkage for **`constexpr`** variables. Off by default unless **`/permissive-`** is specified. |
@@ -40,7 +40,7 @@ Here are the **`/Zc`** compiler options:
| [`/Zc:noexceptTypes[-]`](zc-noexcepttypes.md) | Enforce C++17 **`noexcept`** rules. Off by default unless **`/std:c++17`** or later is specified. |
| [`/Zc:nrvo[-]`](zc-nrvo.md) | Enable optional copy and move elisions. Off by default unless **`/O2`**, **`/permissive-`**, or **`/std:c++20`** or later is specified. |
| [`/Zc:preprocessor[-]`](zc-preprocessor.md) | Use the new conforming preprocessor. Off by default unless **`/std:c11`** or later is specified. |
-| [`/Zc:referenceBinding[-]`](zc-referencebinding-enforce-reference-binding-rules.md) | A UDT temporary won't bind to a nonconst lvalue reference. Off by default unless **`/permissive-`** is specified. |
+| [`/Zc:referenceBinding[-]`](zc-referencebinding-enforce-reference-binding-rules.md) | A temporary value of a user-defined type dosen't bind to a nonconst lvalue reference. Off by default unless **`/permissive-`** is specified. |
| [`/Zc:rvalueCast[-]`](zc-rvaluecast-enforce-type-conversion-rules.md) | Enforce Standard C++ explicit type conversion rules. Off by default unless **`/permissive-`** is specified. |
| [`/Zc:sizedDealloc[-]`](zc-sizeddealloc-enable-global-sized-dealloc-functions.md) | Enable C++14 global sized deallocation functions. On by default. |
| [`/Zc:strictStrings[-]`](zc-strictstrings-disable-string-literal-type-conversion.md) | Disable string-literal to `char*` or `wchar_t*` conversion. Off by default unless **`/permissive-`** is specified. |
@@ -52,8 +52,9 @@ Here are the **`/Zc`** compiler options:
| [`/Zc:tlsGuards[-]`](zc-tlsguards.md) | Generate runtime checks for TLS variable initialization. On by default. |
| [`/Zc:trigraphs[-]`](zc-trigraphs-trigraphs-substitution.md) | Enable trigraphs (obsolete, off by default). |
| [`/Zc:twoPhase-`](zc-twophase.md) | Use nonconforming template parsing behavior (only applicable when **`/permissive-`** is specified, which defaults to conforming). |
+| [`/Zc:u8EscapeEncoding[-]`](zc-u8escapeencoding.md) | Encode integer escape sequences in u8 string literals as-is instead of as utf-8 characters. Off by default. |
| [`/Zc:wchar_t[-]`](zc-wchar-t-wchar-t-is-native-type.md) | **`wchar_t`** is a native type, not a typedef. On by default. |
-| [`/Zc:zeroSizeArrayNew[-]`](zc-zerosizearraynew.md) | Call member `new`/`delete` for 0-size arrays of objects. On by default. |
+| [`/Zc:zeroSizeArrayNew[-]`](zc-zerosizearraynew.md) | Call member `new`/`delete` for `0`-size arrays of objects. On by default. |
For more information about conformance issues in MSVC, see [Nonstandard behavior](../../cpp/nonstandard-behavior.md).
diff --git a/docs/build/reference/zc-u8escapeencoding.md b/docs/build/reference/zc-u8escapeencoding.md
new file mode 100644
index 00000000000..361f7210eea
--- /dev/null
+++ b/docs/build/reference/zc-u8escapeencoding.md
@@ -0,0 +1,53 @@
+---
+title: /Zc:u8EscapeEncoding (numeric escape sequence encoding in u8 strings)
+description: "Learn more about the compiler option /Zc:u8EscapeEncoding (numeric escape sequence encoding in u8 strings)"
+author: Rastaban
+ms.author: philc
+ms.service: visual-cpp
+ms.topic: article
+ms.date: 06/01/2026
+ms.subservice: cpp-lang
+---
+# `/Zc:u8EscapeEncoding` (numeric escape sequence encoding in u8 strings)
+
+Keep the value of numeric escape sequences in `u8` string literals without encoding them as utf-8.
+
+Use this switch to increase cross compatibility or when a non-utf-8 character is embedded in an utf-8 string literal.
+
+## Syntax
+
+> **/Zc:u8EscapeEncoding**[**-**]
+
+## Remarks
+
+In C++, `u8` string literals are utf-8 encoded sequences of `char8_t`. This flag changes the way numeric escape sequences are interpreted in `u8` string literals. The behavior under `/Zc:u8EscapeEncoding` is to encode them in the string as a single 8-bit `char8_t` value. The behavior under `/Zc:u8EscapeEncoding-` is to interpret the value as a unicode code point. When the value is a higher code point in Unicode, it's encoded as a multibyte character. The behavior of universal-character sequences is always to encode them as utf-8 independent of `/Zc:u8EscapeEncoding[-]`.
+
+The following example contains both a hex escape sequence \\__x__ and a universal escape sequence \\__u__. `/Zc:u8EscapeEncoding[-]` affects the encoding of the hex escape sequence, but the universal escape sequence is always encoded as utf-8. The example string also includes the space character, which is encoded as `0x20` in utf-8.
+
+```cpp
+#include
+int main()
+{
+ const char8_t str[] = u8" \x00ff \u00ff ";
+ for(char8_t c : str) {
+ printf("0x%X ", c);
+ }
+ return 0;
+}
+```
+
+Under `/Zc:u8EscapeEncoding`, the escape sequence `\x00ff` is encoded as `0xFF` and the universal-character sequence `\u00ff` is encoded as the utf-8 sequence `0xC3 0xBF`. The code example outputs:
+
+```output
+0x20 0xFF 0x20 0xC3 0xBF 0x20 0x0
+```
+
+Under `/Zc:u8EscapeEncoding-`, the values of both `\x00ff` and `\u00ff` are re-encoded as the utf-8 sequence `0xC3 0xBF`. The code example outputs:
+
+```output
+0x20 0xC3 0xBF 0x20 0xC3 0xBF 0x20 0x0
+```
+
+## See also
+
+[/Zc (Conformance)](zc-conformance.md)
diff --git a/docs/build/reference/zh.md b/docs/build/reference/zh.md
index 3cefaf8e712..3cfa06349a0 100644
--- a/docs/build/reference/zh.md
+++ b/docs/build/reference/zh.md
@@ -1,20 +1,37 @@
---
title: "/ZH (Hash algorithm for calculation of file checksum in debug info)"
-description: "Use the /ZH compiler option to enable MD5, SHA-1, or SHA-256 source file checksums in debug info"
-ms.date: 02/01/2022
-f1_keywords: ["/ZH", "/ZH:MD5", "/ZH:SHA1", "/ZH:SHA_256"]
-helpviewer_keywords: ["/ZH", "/ZH:MD5", "/ZH:SHA1", "/ZH:SHA_256", "/ZH compiler option", "/ZH:MD5 compiler option", "/ZH:SHA1 compiler option", "/ZH:SHA_256 compiler option", "Hash algorithm for file checksum in debug info"]
+description: "Use the /ZH compiler option to enable source file checksums in debug info"
+ms.date: 05/25/2026
+f1_keywords: ["/ZH", "/ZH:MD5", "/ZH:SHA1", "/ZH:SHA_256", "/ZH:SHA384", "/ZH:SHA512"]
+helpviewer_keywords: ["/ZH", "/ZH:MD5", "/ZH:SHA1", "/ZH:SHA_256", "/ZH:SHA384", "/ZH:SHA512", "/ZH compiler option", "/ZH:MD5 compiler option", "/ZH:SHA1 compiler option", "/ZH:SHA_256 compiler option", "/ZH:SHA384 compiler option", "/ZH:SHA512 compiler option", "Hash algorithm for file checksum in debug info"]
---
# `/ZH` (Hash algorithm for calculation of file checksum in debug info)
Specifies which cryptographic hash algorithm to use to generate a checksum of each source file.
+> [!NOTE]
+> The **`/ZH`** option is available in Visual Studio 2019 version 16.4 and later.
+
## Syntax
+::: moniker range="<=msvc-170"
+
> **`/ZH:MD5`**\
> **`/ZH:SHA1`**\
> **`/ZH:SHA_256`**
+::: moniker-end
+
+::: moniker range=">=msvc-180"
+
+> **`/ZH:MD5`**\
+> **`/ZH:SHA1`**\
+> **`/ZH:SHA_256`**\
+> **`/ZH:SHA384`**\
+> **`/ZH:SHA512`**
+
+::: moniker-end
+
## Arguments
**`/ZH:MD5`**\
@@ -26,15 +43,36 @@ Use an SHA-1 hash for the checksum.
**`/ZH:SHA_256`**\
Use an SHA-256 hash for the checksum. This option is the default in Visual Studio 2022 version 17.0 and later.
+::: moniker range=">=msvc-180"
+
+**`/ZH:SHA384`**\
+Use an SHA-384 hash for the checksum.
+
+**`/ZH:SHA512`**\
+Use an SHA-512 hash for the checksum.
+
+::: moniker-end
+
## Remarks
-PDB files store a checksum for each source file, compiled into the object code in the associated executable. The checksum allows the debugger to verify that the source code it loads matches the executable. The compiler and debugger support MD5, SHA-1, and SHA-256 hash algorithms. By default, in Visual Studio 2019 the compiler uses an MD5 hash to generate the checksum. To specify this hash algorithm explicitly, use the **`/ZH:MD5`** option.
+::: moniker range="<=msvc-170"
-Because of a risk of collision problems in MD5 and SHA-1, Microsoft recommends you use the **`/ZH:SHA_256`** option. The SHA-256 hash might result in a small increase in compile times. The **`/ZH:SHA_256`** option is the default in Visual Studio 2022 version 17.0 and later.
+PDB files store a checksum for each source file, compiled into the object code in the associated executable. The checksum allows the debugger to verify that the source code it loads matches the executable. The compiler and debugger support MD5, SHA-1, and SHA-256 hash algorithms.
+Because of a risk of collision problems in MD5 and SHA-1, use the **`/ZH:SHA_256`** option or stronger.
-When more than one **`/ZH`** option is specified, the last option is used.
+::: moniker-end
+
+::: moniker range=">=msvc-180"
+
+PDB files store a checksum for each source file, compiled into the object code in the associated executable. The checksum allows the debugger to verify that the source code it loads matches the executable. The compiler and debugger support MD5, SHA-1, SHA-256, SHA-384, and SHA-512 hash algorithms.
+Because of a risk of collision problems in MD5 and SHA-1, use the **`/ZH:SHA_256`** option or a stronger algorithm. SHA-384 and SHA-512 provide stronger checksums, but they can increase compile time.
-The **`/ZH`** option is available in Visual Studio 2019 version 16.4 and later.
+> [!NOTE]
+> The **`/ZH:SHA384`** and **`/ZH:SHA512`** options aren't supported for IFC (module interface) files. If you compile modules with one of these options, the compiler emits [fatal error C1029](../../error-messages/compiler-errors-1/fatal-error-c1029.md). Use **`/ZH:SHA_256`** or a smaller hash algorithm when you compile C++ modules.
+
+::: moniker-end
+
+When more than one **`/ZH`** option is specified, the last option is used.
### To set this compiler option in the Visual Studio development environment
@@ -44,9 +82,20 @@ The **`/ZH`** option is available in Visual Studio 2019 version 16.4 and later.
1. Select the **Configuration Properties** > **C/C++** > **Command Line** property page.
+::: moniker range=">=msvc-180"
+
+1. Modify the **Additional options** property to add a **`/ZH:MD5`**, **`/ZH:SHA1`**, **`/ZH:SHA_256`**, **`/ZH:SHA384`**, or **`/ZH:SHA512`** option, and then choose **OK**.
+
+::: moniker-end
+
+::: moniker range=">=msvc-160 <=msvc-170"
+
1. Modify the **Additional options** property to add a **`/ZH:MD5`**, **`/ZH:SHA1`**, or **`/ZH:SHA_256`** option, and then choose **OK**.
+::: moniker-end
+
## See also
[Compiler options](compiler-options.md)\
+[Debug Interface Access SDK - IDiaSourceFile::get_checksumType](/visualstudio/debugger/debug-interface-access/idiasourcefile-get-checksumtype)\
[Source server](/windows/win32/debug/source-server-and-source-indexing)
diff --git a/docs/build/sample-profile-guided-optimization.md b/docs/build/sample-profile-guided-optimization.md
new file mode 100644
index 00000000000..9a9b7babe60
--- /dev/null
+++ b/docs/build/sample-profile-guided-optimization.md
@@ -0,0 +1,715 @@
+---
+description: "Learn how to use Sample Profile-Guided Optimization (SPGO) to improve the performance of C and C++ applications."
+title: "Tutorial: Use Sample Profile-Guided Optimization (SPGO) to improve C++ performance"
+ms.date: 05/20/2026
+ms.topic: tutorial
+ai-usage: ai-assisted
+helpviewer_keywords: ["SPGO", "sample profile-guided optimization", "profiling, SPGO", "SPDConvert", "SPTAggregate"]
+---
+# Use Sample Profile Guided Optimization (SPGO) to improve C++ performance
+
+Profile-Guided Optimization (PGO) uses runtime data to help the compiler make better optimization decisions. By using execution profile data collected from representative workloads, PGO enables the compiler to make smarter decisions about inlining, code layout, and hot/cold code separation. These decisions are impossible to make from static analysis alone.
+
+SPGO takes a different approach. Instead of instrumenting your binary and running it through synthetic training scenarios, SPGO uses hardware performance counter sampling collected from your actual release binaries. Modern processors provide hardware sampling capabilities. You can collect these samples with negligible runtime overhead, making it practical to gather runtime profiles directly from production code.
+
+Because SPGO profiles release bits instead of instrumented builds, it enables much more flexibility in where and how you collect data. You can gather runtime profiles from production servers, developer machines, performance labs, or any combination. The result is a binary that runs hot paths more efficiently, with a typical performance speedup of 5-15% depending on the quality of the profile data.
+
+For more information about Sample Profile‑Guided Optimization (PGO) in MSVC and how it improves performance using sampling‑based profiling, see [Introducing Sample Profile Guided Optimization in MSVC](https://devblogs.microsoft.com/cppblog/introducing-sample-profile-guided-optimization-in-msvc/)
+
+In this tutorial, you walk through the complete SPGO workflow: build a sample app, profile it by using `xperf`, prepare the profile data, and rebuild with the profile data. When you finish, you can apply the same process to your own projects.
+
+## Prerequisites
+
+Before you start, make sure you have the following software and hardware.
+
+### Software
+
+- **MSVC build tools for x64/x86/ARM64 v14.51 or later**—Install them through the Visual Studio Installer. Under **Individual Components**, search for "MSVC build tools."
+- **Windows Performance Toolkit (xperf.exe)**—The `xperf` profiler collects sample data during your program's execution. Download the Windows Assessment and Deployment Kit (ADK) from [ADK install](/windows-hardware/get-started/adk-install). When you run the ADK installer, select the **Windows Performance Toolkit** component to get `xperf`. You don't need to install the full ADK.
+- **War and Peace text file**—Used as the sample workload to generate profiling data. Download it from Project Gutenberg: [https://www.gutenberg.org/ebooks/2600](https://www.gutenberg.org/ebooks/2600). Save it as a plain text file in your working directory.
+
+### Hardware requirements
+
+The tutorial has three profiling paths. Which path you use depends on your hardware. You run detection commands in [Choose your profiling method](#choose-your-profiling-method) to find out which path your machine supports. For now, use this table to confirm you meet at least one of the requirements.
+
+| Path | CPU requirement | Notes |
+|------|----------------|-------|
+| **LBR** (best results) | Last Branch Records (LBR) are performance counters provided on Intel Haswell CPUs (4th gen Core, 2013) or later; AMD Zen 4 (2022) or later, ARM64 ARMv9.2-A (2020) or later | Provides the best branch data. For more information about LBR, see [An introduction to last branch records](https://lwn.net/Articles/680985/) |
+| **PMC/IP mode** (good results) | Performance Monitoring Counters (PMC) are supported on any x64 CPU with a performance monitoring unit (PMU) | Works on most modern CPUs where LBR is unavailable. For more information about PMC, see [Recording Hardware Performance (PMU) Events](/windows-hardware/test/wpt/recording-pmu-events) and [Recording Hardware Performance (PMU) Events with Complete Examples](https://devblogs.microsoft.com/performance-diagnostics/recording-hardware-performance-pmu-events-with-complete-examples/#configuring-extended-pmu-counter-configurations5) |
+| **OS timer** (works everywhere) | Any x64 or ARM64 CPU, including Azure VMs and virtual machines | Lower-fidelity samples, but always available |
+
+Most developers on modern x64 desktop hardware have LBR support. VMs and some older hardware have PMC or an OS timer.
+
+## How SPGO works
+
+SPGO collects profile data from your running binary and feeds it back to the compiler when you next build. The compiler uses that data to make better decisions about inlining, code layout, and branch prediction. A convenience is that no instrumentation is required.
+
+The workflow is:
+
+1. Build your binary with the [/spgo](./reference/spgo-enable-sample-profile-guided-optimization.md) linker flag. This step creates an empty **sample profile database** (`.spd` file).
+1. Profile the binary by using `xperf` to produce an ETL trace file.
+1. Convert the ETL to an **SPT** file by using [`SPTAggregate.exe`](sptaggregate.md), then convert the SPT to an **SPD** file by using [`SPDConvert.exe`](spdconvert.md).
+1. Rebuild with the [/spdin](./reference/spdin-use-sample-profile-database.md) linker flag pointing to the populated sample profile database (SPD). The linker applies SPGO optimizations.
+
+The optimizer uses the SPD to answer questions like: which branches are taken most often? Which functions are called in hot loops? This process produces better code layout and inlining decisions than static analysis alone.
+
+SPGO works with both C and C++. The workflow and flags are identical for both languages.
+
+**Best candidates for SPGO:** Large, branch-filled C/C++ applications with tight inner loops. Gains scale with codebase size and branch complexity. The small sample in this tutorial shows around 7% improvement. Larger production codebases often see more improvement.
+
+## Build Process Comparison
+
+This section covers how SPGO fits into the build pipeline if you want to understand the mechanics.
+
+### Normal build process
+
+In a standard C/C++ release build:
+
+- **Inputs:** Source code files (`.cpp`, `.h`) and release-mode compiler flags (`/O2`, `/GL`, and so on).
+- **Process:** The compiler applies standard optimizations such as inlining heuristics, branch prediction assumptions, and code layout decisions based on static analysis alone. It has no data about how the program actually behaves when it runs.
+- **Output:** Executable (`.exe`), DLL files (`.dll`), debug information (`.pdb`).
+
+:::image type="content" source="media/normal-build-process.png" alt-text="Diagram of the normal release build process showing source code files and example compiler switch /GL as inputs flowing to a build step, which produces .exe, .dll, and .pdb outputs." lightbox="media/normal-build-process.png":::
+
+Without runtime data, hot paths and cold paths receive similar treatment.
+
+### SPGO-enabled build process
+
+SPGO adds profiling data as a new input to the build pipeline:
+
+- **Inputs:** Source code, the `.spd` profile file (sample counts from a profiling run), release-mode compiler flags, `/link /spgo`, and `/spdin:` to specify an input SPD file (if not specified, defaults to a .spd using the binary name and located in the obj folder).
+- **Process:** The linker reads the SPD alongside the intermediate code. It uses branch-frequency data to make better inlining, code layout, and branch-ordering decisions. Hot functions get laid out for fast access; cold code moves out of the critical path.
+- **Output:** Optimized executable (`.exe`), optimized DLL files (`.dll`), debug information (`.pdb`), **and a new `.spd` file** for future profiling iterations.
+
+:::image type="content" source="media/sample-profile-guided-optimization-build-process.png" alt-text="Diagram of the SPGO-enabled build process showing source code and profile data files (.spd) as inputs to the build step with an additional linker switch /spgo. The build process outputs optimized .exe, .dll, debug information (.pdb), and new profile data files (.spd)." lightbox="media/sample-profile-guided-optimization-build-process.png":::
+
+The key insight: SPGO moves optimization decisions from compiler and linker heuristics to data-driven choices based on real execution.
+
+### Key flags
+
+| Flag | Type | Purpose |
+|------|------|---------|
+| [`/spgo`](./reference/spgo-enable-sample-profile-guided-optimization.md) | Linker | Enables SPGO. Embeds SPGO metadata in the binary and creates an empty `.spd` output file unless `/spdin` is specified, in which case the specified `.spd` file is used as input. |
+| [`/spdin:`](./reference/spdin-use-sample-profile-database.md) | Linker | Input SPD - provides profile data to the linker for optimization |
+| [`/spd:`](./reference/spd-specify-sample-profile-database.md) | Linker | Output SPD path - specifies where the new SPD is written (optional; defaults to the same directory as the binary). Serves as the input SPD path if `/spdin` isn't specified. |
+| [`/GL`](./reference/gl-whole-program-optimization.md) | Compiler | Whole-program optimization-required for SPGO to work across translation units |
+| [`/O1`, `/O2` (Minimize Size, Maximize Speed)](./reference/o1-o2-minimize-size-maximize-speed.md) | Compiler | Optimize for speed; enables aggressive optimizations that SPGO can enhance |
+
+### How SPGO differs from PGO
+
+PGO (Profile-Guided Optimization) requires you to compile your binary with instrumentation flags (`/GENPROFILE`), run the slower instrumented binary to collect `.pgc` execution count files, then relink with `/USEPROFILE`. The compiler gets exact execution counts but you have to instrument the code first. For more information about this process, see [Profile-guided optimizations](profile-guided-optimizations.md).
+
+SPGO uses hardware CPU performance counters to collect statistical samples from your uninstrumented release binary. Run your existing binary, profile it by using `xperf`, convert the trace to an SPD file, and rebuild. There's no instrumented build and no slowdown during profiling. The compiler gets statistical sampling data instead of exact counts, which is less precise but easier to get and requires no code changes. It also allows profiling of system components or realtime components that are difficult to collect data for with an instrumented approach. You can also profile final/shipping binaries.
+
+This tutorial covers three profiling methods: LBR, PMC, and OS timer. You choose your method in [Choose your profiling method](#choose-your-profiling-method). For a detailed comparison of the normal build process versus the SPGO build process, including a flag reference table, see [Build Process Comparison](#build-process-comparison).
+
+## Configure `perfcore.ini`
+
+> **⚠️ Required:** Without this step, `xperf` doesn't provide the necessary profiling data. Complete this step before running `xperf`.
+
+The Windows Performance Toolkit (WPT) uses `perfcore.ini`, located if you installed the WPT in the default location at `C:\Program Files (x86)\Windows Kits\10\Windows Performance Toolkit\perfcore.ini`, to register the DLL providers it needs for SPGO.
+
+Open Windows Notepad as Administrator. Then open `perfcore.ini`. Find the DLL list section and add the following entries, one per line:
+
+```
+perf_lbr.dll
+perf_spt.dll
+perf_hv.dll
+```
+
+If `xperf.exe` isn't installed, see [General issues](#general-issues-all-paths) to install it.
+
+Save and close `perfcore.ini`. The DLL files already ship in the same directory as `xperf.exe` so you don't need to copy them anywhere. You're only registering them in `perfcore.ini`. Ensure that `xperf` is in your path.
+
+## Create the sample app
+
+The sample app for this tutorial is a C++ program that reads text from standard input and produces a line count, word count, total character count, a character frequency table, and elapsed time to process the file in milliseconds. It's written in C++, but SPGO also works with C. The workflow is identical for C projects.
+
+Create a file named `textCount.cpp` in your working directory and add the following source code:
+
+```cpp
+// textCount.cpp : Text Statistics Counter
+// Counts words, lines, and character frequencies from standard input
+// Usage: textCount < file.txt
+
+#include
+#include
+#include