KEMBAR78
CPP Overview MSVC 170 | PDF | C++ | Microsoft Windows
0% found this document useful (0 votes)
102 views509 pages

CPP Overview MSVC 170

The document provides comprehensive information on using C and C++ in Visual Studio 2022, detailing tools, libraries, and features for developing applications across various platforms. It covers installation, project creation, debugging, testing, and deployment, along with updates and improvements in newer versions. Additionally, it includes resources for learning C++, community support, and references for language standards and libraries.

Uploaded by

darkraven252
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
102 views509 pages

CPP Overview MSVC 170

The document provides comprehensive information on using C and C++ in Visual Studio 2022, detailing tools, libraries, and features for developing applications across various platforms. It covers installation, project creation, debugging, testing, and deployment, along with updates and improvements in newer versions. Additionally, it includes resources for learning C++, community support, and references for language standards and libraries.

Uploaded by

darkraven252
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 509

Tell us about your PDF experience.

C and C++ in Visual Studio


Article • 09/30/2022

7 Note

This developer documentation applies to Visual Studio 2022. To see the


documentation for your preferred version of Visual Studio, use the Version selector
control. It's found at the top of the table of contents on this page.

If you're looking for a Microsoft Visual C++ Redistributable package so that you
can run a program, see the latest supported Visual C++ downloads.

Microsoft Visual C++ (MSVC) refers to the C++, C, and assembly language development
tools and libraries available as part of Visual Studio on Windows. These tools and
libraries let you create native Windows desktop and server applications, Universal
Windows Platform (UWP) apps, or managed apps and libraries that use the .NET
Framework. Create cross-platform libraries and apps that run on Windows, Linux,
Android, and iOS. You can use MSVC to write anything from simple console apps to the
most sophisticated and complex apps for Windows desktop. Write device drivers and
operating system components or cross-platform games for mobile devices. Target
anything from the smallest IoT devices to multi-server high performance computing in
the Azure cloud.

Visual Studio 2015, 2017, 2019, and 2022 can be installed side-by-side. You can use
Visual Studio 2019 (compiler toolset v142) or Visual Studio 2017 (v141) to edit and build
programs using the toolset from Visual Studio 2017 (v141) and Visual Studio 2015
(v140).

What's new for C++ in Visual Studio


What's New for C++ in Visual Studio 2022
Find out what's new in Visual Studio 2022.

What's New for C++ in Visual Studio 2019


Find out what's new in Visual Studio 2019.

What's New for C++ in Visual Studio 2017


Find out what's new in Visual Studio 2017.
What's New for C++ in Visual Studio 2003 through 2015
Find out what was new in C++ for each version of Visual Studio from 2003 through
2015.

C++ conformance improvements in Visual Studio


Learn about C++ conformance improvements in Visual Studio.

Microsoft C/C++ language conformance


Find feature-level language conformance status in the MSVC compiler by Visual Studio
version.

Microsoft C/C++ change history 2003 - 2015


Learn about the breaking changes in previous versions.

Install Visual Studio C++ and upgrade from


earlier versions
Install C++ support in Visual Studio
Download Visual Studio and install the Microsoft C/C++ toolset.

Microsoft C++ porting and upgrading guide


Guidance for porting code and upgrading projects to Visual Studio 2015 or later. Take
advantage of greater compiler conformance to the C++ standard, greatly improved
compilation times, and security features such as Spectre mitigation.

C++ tools and features in Visual Studio editions


Find out about different Visual Studio editions.

Supported platforms
Find out which platforms the Microsoft C/C++ compiler supports.

Learn C++ using Visual Studio


Welcome back to C++
Learn more about modern C++ programming techniques based on C++11 and later
that enable you to write fast, safe code and avoid many of the pitfalls of C-style
programming.

Standard C++
Learn about C++, get an overview of Modern C++, and find links to books, articles,
talks, and events
Learn Visual Studio and make your first C++ project
Start learning how to write C++ in Visual Studio.

Visual Studio C++ samples


Information about the C++ code samples provided by Microsoft.

Visual Studio C/C++ development tools


Overview of C++ development in Visual Studio
How to use the Visual Studio IDE to create projects, edit code, link to libraries, compile,
debug, create unit tests, do static analysis, deploy, and more.

Projects and build systems


How to create and configure Visual Studio C++ projects, CMake projects, and other
kinds of projects with MSVC compiler and linker options.

Writing and refactoring C++ code


How to use the productivity features in the C++ editor to refactor, navigate, understand
and write code.

Debugging native code


Use the Visual Studio debugger with C++ projects.

Code analysis for C/C++ overview


Use SAL annotations or the C++ Core Guidelines checkers to perform static analysis.

Write unit tests for C/C++ in Visual Studio


Create unit tests using the Microsoft Unit Testing Framework for C++, Google Test,
Boost.Test, or CTest.

Write C/C++ applications using Visual Studio


Windows C++ desktop application types
Learn how to create traditional native C++ desktop applications for Windows.

.NET programming with C++/CLI


Learn how to create DLLs that enable interoperability between native C++ and .NET
programs written in languages such as C# or Visual Basic.

Universal Windows Apps (C++)


Find guides and reference content on the Windows Developer Center. For information
about developing UWP apps, see Intro to the Universal Windows Platform and Create
your first UWP app using C++.
Linux programming
Use the Visual Studio IDE to code and deploy to a remote Linux machine for compilation
with GCC.

Create C/C++ DLLs in Visual Studio


Find out how to use Win32, ATL, and MFC to create Windows desktop DLLs. Provides
information about how to compile and register your DLL.

Parallel programming
Learn how to use the Parallel Patterns Library, C++ AMP, OpenMP, and other features
that are related to multithreading on Windows.

Security best practices


Learn how to protect applications from malicious code and unauthorized use.

Cloud and web programming


In C++, you have several options for connecting to the web and the cloud.

Data access
Connect to databases using ODBC and OLE DB.

Text and strings


Learn about working with different text and string formats and encodings for local and
international development.

C/C++ language reference


C++ language reference
The reference guide to the Microsoft implementation of the C++ programming
language.

C language reference
The reference guide to the Microsoft implementation of the C programming language.

C/C++ preprocessor reference


A common reference to the shared C and C++ language preprocessor.

C++/CX language reference


The reference guide to the Microsoft extensions to the C++ language for creating C++
Universal Windows Platform apps, C++ Windows runtime components that can be
consumed by JavaScript-based Windows apps, and Windows DirectX games and
graphics-intensive apps.
C++/CLI language reference
The ECMA standard for the C++/CLI programming language.

Compiler intrinsics and assembly language


Guides to the compiler intrinsics supported or implemented by the Microsoft C/C++
compilers on each platform.

C/C++ libraries available in Visual Studio


The following sections provide information about the different C and C++ libraries that
are included in Visual Studio.

C runtime library reference


Includes security-enhanced alternatives to functions that are known to pose security
issues.

C++ standard library


The C++ Standard Library.

Active Template Library (ATL)


Support for COM components and apps.

Microsoft Foundation Class (MFC) libraries


Support for creating desktop apps that have traditional or Office-style user interfaces.

Parallel Patterns Library (PPL)


Asynchronous and parallel algorithms that execute on the CPU.

C++ AMP (C++ Accelerated Massive Parallelism)


Massively parallel algorithms that execute on the GPU.

Windows Runtime Template Library (WRL)


Universal Windows Platform (UWP) apps and components.

.NET programming with C++/CLI


Programming for the common language runtime (CLR).

Third-party open source C++ libraries in Visual


Studio
The cross-platform vcpkg command-line tool greatly simplifies the discovery and
installation of over 900 C++ open source libraries. For more information, see vcpkg.
Visual Studio C++ feedback and community
Microsoft Learn Q&A
Microsoft Learn hosts searchable forums for questions and answers. Add a C++ tag to
your post for community assistance on C++-related issues.

How to report a problem with the Microsoft C/C++ toolset


Learn how to create effective error reports against the Microsoft C/C++ toolset
(compiler, linker, and other tools), and ways to submit your report.

Microsoft C++ Team Blog


Learn more about new features and the latest information from the developers of the
C++ tools in Visual Studio.

Visual Studio C++ Developer Community


Get help, file bugs, and make suggestions for C++ in Visual Studio.

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Overview of C++ development in Visual
Studio
Article • 03/02/2023

As part of the Visual Studio Integrated Development Environment (IDE), Microsoft C++
(MSVC) shares many windows and tools in common with other languages. Many of
those, including Solution Explorer, the code editor, and the debugger, are documented
under Visual Studio IDE. Often, a shared tool or window has a slightly different set of
features for C++ than for other languages. A few windows or tools are only available in
Visual Studio Professional or Visual Studio Enterprise editions.

In addition to shared tools in the Visual Studio IDE, MSVC has several tools specifically
for native code development. These tools are also listed in this article. For a list of which
tools are available in each edition of Visual Studio, see C++ Tools and Features in Visual
Studio Editions.

Create projects
A project is basically a set of source code files and resources such as images or data files
that are built into an executable program or library.

Visual Studio provides support for any project system or custom build tools that you
wish to use, with full support for IntelliSense, browsing and debugging:

MSBuild is the native project system for Visual Studio. When you select File > New
> Project from the main menu, you see many kinds of MSBuild project templates
that get you started quickly developing different kinds of C++ applications.
In general, you should use these templates for new projects unless you are using
existing CMake projects, or you are using another project system. For more
information, see Creating and managing MSBuild-based projects.

CMake is a cross-platform build system that is integrated into the Visual Studio IDE
when you install the Desktop development with C++ workload. You can use the
CMake project template for new projects, or simply open a folder with a
CMakeLists.txt file. For more information, see CMake projects in Visual Studio.

Any other C++ build system, including a loose collection of files, is supported via
the Open Folder feature. You create simple JSON files to invoke your build
program and configure debugging sessions. For more information, see Open
Folder projects for C++.

Add to source control


Source control enables you to coordinate work among multiple developers, isolate in-
progress work from production code, and backup your source code. Visual Studio
supports Git and Team Foundation Version Control (TFVC) through its Team Explorer
window.
For more information about Git integration with repos in Azure, see Share your code
with Azure Repos and Visual Studio. For information about Git integration with GitHub,
see Visual Studio and GitHub: Better together .

Obtain libraries
Use the vcpkg package manager to obtain and install third-party libraries. Over 1700
open-source library packages are currently available in the catalog.

Create user interfaces with designers


If your program has a user interface, you can use a designer to quickly populate it with
controls such as buttons, list boxes and so on. When you drag a control from the
toolbox window and drop it onto the design surface, Visual Studio generates the
resources and code required to make it all work. You then write the code to customize
the appearance and behavior.
For more information about designing a user interface for a Universal Windows
Platform app, see Design and UI.
For more information about creating a user interface for an MFC application, see
MFC Desktop Applications.
For information about Win32 Windows programs, see Windows C++ desktop
application types.

Write code
After you create a project, all the project files are displayed in the Solution Explorer
window. (A solution is a logical container for one or more related projects.) When you
click on a .h or .cpp file in Solution Explorer, the file opens up in the code editor.
The code editor is a specialized word processor for C++ source code. It color-codes
language keywords, method and variable names, and other elements of your code to
make the code more readable and easier to understand. It also provides tools for
refactoring code, navigating between different files, and understanding how the code is
structured. For more information, see Writing and refactoring code.

Add and edit resources


A Windows program or DLL usually includes some resources, such as dialogs, icons,
images, localizable strings, splash screens, database connection strings, or any arbitrary
data. Visual Studio includes tools for adding and editing resources. For more
information, see Working with Resource Files.

Build (compile and link)


Choose Build > Build Solution on the menu bar, or enter the Ctrl+Shift+B key
combination to compile and link a project. Build errors and warnings are reported in the
Error List (Ctrl+\, E). The Output Window (Alt+2) shows information about the build
process.
For more information about configuring builds, see Working with Project Properties and
Projects and build systems.

You can also use the compiler (cl.exe) and many other build-related standalone tools
such as NMAKE and LIB directly from the command line. For more information, see Build
C/C++ code on the command line and C/C++ Building Reference.

Debug
You can start debugging by pressing F5. Execution pauses on any breakpoints you have
set (by pressing F9). You can also step through code one line at a time (F10), view the
values of variables or registers, and even in some cases make changes in code and
continue debugging without re-compiling. The following illustration shows a debugging
session in which execution is stopped on a breakpoint. The values of the data structure
members are visible in the Watch Window.
For more information, see Debugging in Visual Studio.

Test
Visual Studio includes the Microsoft Unit Test Framework for C++, as well as support for
Boost.Test, Google Test, and CTest. Run your tests from the Test Explorer window:
For more information, see Verifying Code by Using Unit Tests and Write unit tests for
C/C++ in Visual Studio.

Analyze
Visual Studio includes static code analysis tools that can detect potential problems in
your source code. These tools include an implementation of the C++ Core Guidelines
rules checkers. For more information, see Code analysis for C/C++ overview.

Deploy completed applications


You can deploy both traditional desktop applications and UWP apps to customers
through the Microsoft Store. Deployment of the CRT is handled automatically behind
the scenes. For more information, see Publish Windows apps and games.

You can also deploy a native C++ desktop to another computer. For more information,
see Deploying Desktop Applications.

For more information about deploying a C++/CLI program, see Deployment Guide for
Developers,

Next steps
Explore Visual Studio further by following along with one of these introductory articles:

Learn to use the code editor

Learn about projects and solutions

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


What's new for C++ in Visual Studio
2022
Article • 08/12/2024

Visual Studio 2022 brings many updates and fixes to the Microsoft C++ compiler and
tools. The Visual Studio IDE also offers significant improvements in performance and
productivity, and now runs natively as a 64-bit application.

For more information on what's new in all of Visual Studio, see What's new in
Visual Studio 2022.
For information about what's new in the C++ docs, see Microsoft C++ docs:
What's new.
For information about version build dates, see Visual Studio 2022 Release History.

What's new for C++ in Visual Studio version


17.11
Released August 2024

ノ Expand table

For more information about See

What's new for C++ developers What's New for C++ Developers in
Visual Studio 2022 17.11

Standard Library (STL) merged C++26 and C++23 STL Changelog 17.11
features, C++20 defect reports, LWG issue resolutions,
performance improvements, enhanced behavior, and fixed
bugs

New features in the Visual Studio 17.11 IDE Visual Studio 2022 version 17.11
Release Notes

C++ language conformance improvements in Visual C++ Conformance improvements,


Studio 2022 17.11 behavior changes, and bug fixes in
Visual Studio 2022 17.11

A partial list of new features:

Standard Library Enhancements:


The formatted output implementation now includes std::range_formatter and
formatters for std::pair and std::tuple .
Added support for std::println() with no arguments. This prints a blank line
as proposed in P3142R0 .
Improved vectorization for several algorithms including
replace_copy() , replace_copy_if() , ranges::replace_copy ,
ranges::replace_copy_if , find_first_of() and ranges::find_first_of , for 8-bit

and 16-bit elements, mismatch() , ranges::mismatch , count() ranges::count ,


find() , ranges::find , ranges::find_last , and ranges::iota .

Game development in C++


You can now add common Unreal Engine class templates, modules, and plugins
from within Visual Studio. For more information, see Add Unreal Engine classes,
modules, and plugins in Visual Studio.
The new Unreal Engine toolbar provides quick access to Unreal Engine related
actions from within Visual Studio. The toolbar allows you to quickly attach to
Unreal Engine processes, rescan the Blueprints cache, quickly access the Unreal
Engine Log, and provides quick access to the Unreal Engine Configuration Page
for Visual Studio. For more information, see Unreal Engine Toolbar.
You can now filter trace results by project. Also, results in each row show the
relative path and file name instead of the full path. Results grouping in the
Included Files view is also improved:

CMake debugging
You can now debug your CMake scripts and CMakeLists.txt files in the Visual
Studio debugger for CMake projects that target Linux via Windows Subsystem
for Linux (WSL) or SSH. To start a CMake debugging session in Visual Studio, set
a breakpoint in your CMakeLists.txt file and then navigate to Project >
Configure Cache with CMake Debugging.

Copilot
When you hover over symbols in the code editor, click the Copilot Tell me more
button in the Quick Info dialog to learn more about a given symbol:

GitHub Copilot can generate naming suggestions for your identifiers (variables,
methods, or classes) based on how your identifier is used and the style of your
code.

You need an active GitHub Copilot subscription . Right-click the variable you wish
to rename, and choose Rename ( Ctrl+R , Ctrl+R ). Select the GitHub Copilot
sparkle icon to generate naming suggestions.

Debugging
Conditional breakpoints in C++ are significantly faster.

Diagnostics improvements
Improved diagnostics when calling std::get<T> on a std::tuple that has
multiple instances of T in its template arguments. MSVC used to report:
error C2338: static_assert failed: 'duplicate type T in get<T>(tuple)' .

Now it reports:
error C2338: static_assert failed: 'get<T>(tuple<Types...>&) requires T to

occur exactly once in Types.(N4971 [tuple.elemm]/5)'

Improved diagnostics when std::ranges::to is unable to construct the


requested result. MSVC used to report:
error C2338: static_assert failed: 'the program is ill-formed per N4950
[range.utility.conv.to]/2.3'

Now it reports:
error C2338: static_assert failed: 'ranges::to requires the result to be

constructible from the source range, either by using a suitable

constructor, or by inserting each element of the range into the default-


constructed object. (N4981 [range.utility.conv.to]/2.1.5)'

What's new for C++ in Visual Studio version


17.10
Released May 2024

ノ Expand table

For more information about See

What's new for C++ developers What's new for C++ Developers in
Visual Studio 2022 17.10

Standard Library (STL) merged C++26 and C++23 STL Changelog 17.10
features, C++20 defect reports, LWG issue resolutions,
performance improvements, enhanced behavior, and fixed
bugs

New features in the Visual Studio 17.10 IDE Visual Studio 2022 version 17.10
Release Notes

C++ language conformance improvements in Visual C++ Conformance improvements,


Studio 2022 17.10 behavior changes, and bug fixes in
Visual Studio 2022 17.10

A partial list of new features:

MSVC Toolset Update: The MSVC toolset version is updated from 19.39 to 19.40.
This may affect projects that have version assumptions. For more information
about some ways in which this will affect projects that assume that MSVC versions
are all 19.3X for Visual Studio 2022 releases, see MSVC Toolset Minor Version
Number 14.40 in VS 2022 v17.10 .
Standard Library Enhancements: The standard library added support for P2510R3
Formatting Pointers , which brings the set of format specifiers for pointers when
using std::format more in line with those that already exist for integers. Improved
the vectorized implementations of std::min_element , std::ranges::min , and
friends.
Build Insights: Now provides template instantiation information. See Templates
View for Build Insights in Visual Studio or the Pure Virtual C++ - Templates view
for Build Insights in Visual Studio recording.
Unreal Engine Plugin: There's a new opt-in feature for the Unreal Engine Plugin to
run in the background, reducing startup costs. This is an opt-in feature that is
activated via Tools > Options > Unreal Engine.
New features for Linux: See New Linux Development Features in Visual Studio .
CMake Targets: You can now pin targets in the CMake Targets View.
Connection Manager UX: The user experience provides a more seamless
experience when connecting to remote systems. For more information, see
Usability Improvements in the Visual Studio Connection Manager .
Pull request comments: You can now view GitHub and Azure DevOps comments
directly in your working file. Enable the feature flag, Pull Request Comments in
Options > Environment > Preview Features and checkout the pull request branch
to get started.
AI-Generated Content: GitHub Copilot can now draft pull request descriptions.
Requires an active GitHub Copilot subscription. Try it out by clicking the Add AI
Generated Pull Request Description sparkle pen icon within the Create a Pull
Request window.
Image Preview: Hover over an image path to see a preview with size details. The
size is capped to 500 px wide and high.

Breakpoint/Tracepoint Creation: You can now create conditional breakpoints or


tracepoints directly from expressions in the source code from the right-click menu.
This works on property or field names and values from autos, locals, watch
windows, or DataTips.
Attach to Process Dialog: The functionality provided by the Attach to Process
dialog is more user-friendly. You can now easily switch between tree and list views,
organize processes better with collapsible sections, and select code types with a
simplified combobox. Also, the "Select/Track Window" feature is now easier to use,
allowing two-way tracking: selecting a process highlights its window, and clicking
on a window selects its process.
GitHub Copilot Integration: GitHub Copilot and Copilot Chat extensions are now
unified and now ship directly in Visual Studio. To install it, install the GitHub
Copilot component in the Visual Studio Installer:

The GitHub Copilot interface is in the top-right corner of Visual Studio. To use it,
you need an active GitHub Copilot subscription.

What's new for C++ in Visual Studio version


17.9
Released Feb 2024

ノ Expand table

For more information about See

What's new for C++ developers What's new for C++ Developers in
Visual Studio 2022 17.9

Standard Library (STL) merged C++23 features, STL Changelog 17.9


performance improvements, enhanced behavior, LWG
issue resolutions, and fixed bugs

New features in the Visual Studio 17.9 IDE Visual Studio 2022 version 17.9 Release
Notes
For more information about See

C++ language conformance improvements in Visual C++ Conformance improvements,


Studio 2022 17.9 behavior changes, and bug fixes in
Visual Studio 2022

Summary of C++ backend updates MSVC Backend updates since Visual


Studio 2022 version 17.3

A partial list of new features:

#include diagnostics, which provides a detailed analysis of your #include

directives. Activate this feature by right-clicking an #include and choosing


#include directives > Turn #include directive diagnostics on. Above each
#include is the number of times your code references that #include file. Click the

reference link to navigate to where your code uses something from that header
file. To view the build time of your #include directives, run Build Insights by
navigating to Build > Run Build Insights on Solution > Build.

Memory layout visualization, which shows how memory is arranged for your
classes, structs, and unions. Hover over a type and choose the Memory Layout link
in the Quick Info to open a dedicated window displaying the memory layout of the
selected type. Hovering over individual data types within this window provides
detailed information about their size and offset within the type.
You can now specify your own custom CMake executable. This feature is useful if
you want to use a specific version of CMake that isn't shipped with Visual Studio.
Navigate to Tools > Options and select CMake > General. Select Enable custom
CMake executable and specify the directory path of your CMake executable.
Improved IntelliSense for Unreal Engine projects.
Improved C++23 support: std::format and std::span formattable , range_format ,
format_kind , and set_debug_format() as part of P2286R8 Formatting Ranges
<mdspan> per P0009R18 and subsequent wording changes that were applied to
the C++23 Standard. Also, format() can format pointers per P2510R3 .

What's new for C++ in Visual Studio version


17.8
Released Nov 2023

ノ Expand table

For more information about See

What's new for C++ developers What's new for C++ Developers in
Visual Studio 2022 17.8

Standard Library (STL) merged C++26, C++23 features, STL Changelog 17.8
C++20 extensions, LWG issue resolutions, performance
improvements, enhanced behavior, and fixed bugs

New features in the Visual Studio 17.8 IDE Visual Studio 2022 version 17.8
Release Notes

C++ language conformance improvements in Visual C++ Conformance improvements,


Studio 2022 17.8 behavior changes, and bug fixes in
For more information about See

Visual Studio 2022

An overview of C++ improvements in Visual Studio, VS A year of C++ improvements


Code, and vcpkg during 2023

A partial list of new features:

C++ structured diagnostics in the Output window and a new problem details
window that provides more information about the error. For more information, see
Structured SARIF Output and Problem Details Window.
A feature that lets you visualize the size and alignment of your classes, structs,
unions, base types, or enums even before the code is compiled. Hover over the
identifier and a Quick Info displays the size and alignment information.
A feature that suggests when to mark member functions const because they don’t
modify the object’s state. Hover over a member function and click the light bulb
icon to mark the function as const .
Visual Studio now prompts you to mark global functions as static via a screwdriver
icon that appears by the function name. Click the screwdriver icon to mark the
function as static.
Unused #include directives are dimmed in the editor. You can hover over a
dimmed include and use the light bulb menu to either remove that include or all
unused includes. You can also add #include directives for entities that are
indirectly included via other headers. For more information, see Clean up C/C++
includes in Visual Studio.
More Unreal Engine support:
Unreal Engine Test Adapter lets you discover, run, manage, and debug your
Unreal Engine tests without leaving the Visual Studio IDE.
With Unreal Engine Code Snippets, you can find common Unreal Engine
constructs as snippets in your member list.
Build Insights is now integrated with Visual Studio 2022 and works with MSBuild
and CMake projects using MSVC. You can now see additional information about
the compilation of a function such as how long it took to compile and the
number of ForceInlines, and the impact of header files on build time. For more
information, see Tutorial: Troubleshoot function inlining on build time and
Tutorial: Troubleshoot header file impact on build time.
Remote Linux unit test support now lets you run your CTest and GTest tests on
your remote Linux machines from Visual Studio’s Test Explorer, just like your local
tests.
What's new for C++ in Visual Studio version
17.7
Released Aug 2023

ノ Expand table

For more information about See

What's new for C++ developers What’s new for C++ Developers in
Visual Studio 2022 17.7

New C++ features specific to game development Unleashing the Power of Visual Studio
2022 for C++ Game Development

Standard Library (STL) merged C++23 features, LWG STL Changelog 17.7
issue resolutions, performance improvements,
enhanced behavior, and fixed bugs

New features in the Visual Studio 17.7 IDE Visual Studio 2022 version 17.7 Release
Notes

C++ language conformance improvements in Visual C++ Conformance improvements,


Studio 2022 17.7 behavior changes, and bug fixes in
Visual Studio 2022

A partial list of new features:

Faster debugging sessions and faster project load times


Step-by-step visualization of macro expansion
One-click download for Windows Subsystem for Linux (WSL)
Improved support for Doxygen comments
C++ Build Insights for game development
Added /std:clatest for the C compiler.
Unreal Engine project improvements such as faster IntelliSense and syntax
colorization, the ability to find all Unreal Engine Blueprint references, and more.

What's new for C++ in Visual Studio version


17.6
Released May 2023

ノ Expand table
For more information about See

What's new for C++ developers What’s New for C++ Developers in
Visual Studio 2022 17.6

Standard Library (STL) merged C++23 features, LWG STL Changelog 17.6
issue resolutions, performance improvements,
enhanced behavior, and fixed bugs

New features in the Visual Studio 17.6 IDE Visual Studio 2022 version 17.6 Release
Notes

C++ language conformance improvements in Visual C++ Conformance improvements,


Studio 2022 17.6 behavior changes, and bug fixes in
Visual Studio 2022

A partial list of new features includes:

CMake script debugging


Built-in support for High Level Shading Language (HLSL)
Unreal Engine Log viewer
VCPKG is now added by default
Initial support for C++20 in C++/CLI projects and some C++23 standard library
features for ranges.

What's new for C++ in Visual Studio version


17.5
Released Feb 2023

ノ Expand table

For more information about See

What's new for C++ developers What’s New for C++


Developers in Visual Studio
2022 17.5

Standard Library (STL) merged C++23 features, LWG issue STL Changelog 17.5
resolutions, performance improvements, enhanced behavior,
and fixed bugs

New features in the Visual Studio 17.5 IDE Visual Studio 2022 version 17.5
Release Notes

A partial list of new features includes:


std::move , std::forward , std::move_if_noexcept , and std::forward_like now

don't produce function calls in generated code, even in debug mode. This change
avoids named casts causing unnecessary overhead in debug builds. /permissive-
(or an option that implies it, such as /std:c++20 or std:c++latest ) is required.

Added [[msvc::intrinsic]]. You can apply this attribute to nonrecursive functions


consisting of a single cast, which take only one parameter.

Added support for Linux Console in the Integrated Terminal, which allows for
terminal I/O.

Added initial experimental support for C11 atomic primitives ( <stdatomic.h> ). You
can enable this experimental feature with the /experimental:c11atomics option in
/std:c11 mode or later.

Added a new set of experimental high-confidence checks to the Lifetime Checker


for reduced noise.

A new preview feature, Remote File Explorer, lets you view the file directory on
your remote machines within VS, and upload and download files to it.

Changed versioning of CMake executables shipped with Visual Studio to match


Kitware versions.

Added support for Hot Reload to the CMake Project template.

Go To Definition for C++ now uses a more subtle indicator of the operation taking
more time, replacing the modal dialog from previous versions.

Started rollout of an experiment providing more smart results in the C++


autocompletion and member list. This functionality was previously known as
Predictive IntelliSense but now uses a new presentation method.

We now ship a native Arm64 Clang toolset with our LLVM workload, allowing
native compilation on Arm64 machines.

Added localization to the Image Watch Extension (This extension is available in


the Marketplace, and isn't bundled through the Visual Studio Installer).

Added support for opening a Terminal window into the currently running
Developer Container.

Made several improvements to IntelliSense macro expansion. Notably, we enabled


recursive expansion in more contexts, and we added options to the pop up to copy
the expansion to the clipboard or expand the macro inline.
Concurrent monitoring is now supported in the Serial Monitor. Concurrent
monitoring allows you to monitor multiple ports at the same time side by side.
Press the plus button to open another Serial Monitor and get started.

You can now view properties from base classes modified in an Unreal Blueprint
asset without leaving Visual Studio. Double-click in a Blueprint reference for a C++
class or property to open the UE Asset Inspector in Visual Studio.

Enabled running DevContainers on a remote Linux machine.

Enabled selection of multiple targets to build in the CMake Targets view.

Added support for CMakePresets.json version 5. See the CMake documentation


for information of new features.

Enabled Test Explorer to build and test multiple CMake targets in parallel.

Added "Open container in terminal" option to Dev Containers.

Implemented standard library features:


P2508R1 basic_format_string , format_string , wformat_string

P2322R6 ranges::fold_left , ranges::fold_right , and so on.

P2321R2 views::zip (doesn't include zip_transform , adjacent , and


adjacent_transform )

What's new for C++ in Visual Studio version


17.4
Released Nov 2022

ノ Expand table

For more information about See

What's new for C++ developers What’s New for C++ Developers in
Visual Studio 2022 17.4

Standard Library (STL) merged C++23 features, LWG STL Changelog 17.4
issue resolutions, performance improvements,
enhanced behavior, and fixed bugs

New features in the Visual Studio 17.4 IDE Visual Studio 2022 version 17.4 Release
Notes
For more information about See

C++ language conformance improvements in Visual C++ Conformance improvements,


Studio 2022 17.4 behavior changes, and bug fixes in
Visual Studio 2022

A partial list of new features in 17.4:

Improved compiler error messages to provide more correct and useful information,
especially for concepts.

Added experimental MSVC option /experimental:log<directory> to output


structured SARIF diagnostics to the specified directory.

Added support for C23 attributes to IntelliSense and continued progress in C++20
modules support.

Improved indexing performance when opening a new solution. Large projects


could see a 20-35% improvement from 17.3.

Improved Named Return Value Optimization (NRVO):


NRVO is enabled for cases that involve exception handling or loops.
NRVO is enabled even under /Od if the user passes the /Zc:nrvo option, or
/std:c++20 or later, or /permissive- .

You can now disable NRVO with the /Zc:nrvo- option.

Upgraded the version of LLVM shipped with Visual Studio to 15.0.1. For more
information on what is available, see the LLVM and Clang release notes.

Added support to Visual Studio for vcpkg artifacts with CMake projects. For
projects that include a vcpkg manifest, the environment is activated automatically
on project open. Learn more about this feature in the vcpkg environment
activation in Visual Studio blog post.

You can now use Dev Containers for your C++ projects. Learn more about this
feature in our Dev Containers for C++ blog post.

IntelliSense now respects the order of preincluded headers when one of them is a
PCH. Previously, when a PCH was used via /Yu and force-included via /FI ,
IntelliSense would always process it first, before any other headers included via
/FI . This behavior didn't match the build behavior. With this change, /FI headers

are processed in the order they're specified.

Removed internal prefixes from CTest names in Test Explorer.


Updated the version of CMake shipped with Visual Studio to version 3.24.1. For
details of what is available, see the CMake release notes .

Android SDK update:


Ant scripts were removed, so users no longer see Ant-based templates in the
New Project dialog. For help migrating from Ant templates to Gradle templates,
see Migrating Builds From Apache Ant
Added support for building with NDK 23 and 24
Updated NDK component to the LTS version 23

Added vectorized implementations of ranges::min_element() ,


ranges::max_element() , and ranges::minmax_element()

We continue to track the latest developments in C++ standardization. Support for


these C++23 features is available by including /std:c++latest in your compiler
options:

P2302R4 ranges::contains , ranges::contains_subrange

P2499R0 string_view Range Constructor Should Be explicit

P0849R8 auto(x) : decay-copy In The Language

(The compiler part isn't implemented yet. The library part was implemented in
C++20 mode when Ranges support was initially implemented.)

P0881R7 <stacktrace>

P2301R1 Add A pmr Alias For std::stacktrace

P1328R1 constexpr type_info::operator==()

P2440R1 ranges::iota , ranges::shift_left , ranges::shift_right

P2441R2 views::join_with

Added an option "Navigation after Create Declaration/Definition" to allow you to


choose the navigation behavior of the Create Declaration/Definition feature. You
can select between peeking (the default) or opening the document, or no
navigation.

Arm64 builds of Visual Studio now bundle Arm64 versions of CMake and Ninja.

Added support for CMake Presets version 4. For details of what is available, see the
CMake release notes .
Remote system connections using the Connection Manager now support SSH
ProxyJump. ProxyJump is used to access an SSH host via another SSH host (for
example, to access a host behind a firewall).

What's new for C++ in Visual Studio version


17.3
Released Aug 2022

ノ Expand table

For more information about See

What's new for C++ developers C++ improvements in 17.3

Standard Library (STL) merged C++23 features, LWG STL Changelog 17.3
issue resolutions, performance improvements,
enhanced behavior, and fixed bugs

New features in the Visual Studio 17.3 IDE Visual Studio 2022 version 17.3 Release
Notes

C++ language conformance improvements in Visual C++ Conformance improvements,


Studio 2022 17.3 behavior changes, and bug fixes in
Visual Studio 2022

A partial list of new features in 17.3:

The Arm64EC toolchain is no longer marked as experimental and is ready for


production use.
The Visual Studio Terminal can now be used as an SSH client with your stored SSH
connections. With the C++ for Linux Tools installed, open the Terminal tool
window. The Terminal dropdown is populated with your stored connections. When
you select a connection, a new Terminal window opens inside Visual Studio that
shows a pseudo-terminal on your remote system. Control characters, colors, and
cursor positional awareness are all supported.
Visual Studio can now add Unreal Engine class templates for your UE projects. To
try this feature, ensure IDE support for Unreal Engine is selected in the Game
development with C++ workload in the Visual Studio Installer. When you're
working on a UE project, right-click in the project or a folder/filter and select Add
> UE Class.
Go to Definition now remembers the prior signature and navigates accordingly
when a better match isn't available (for example, after you manually change the
signature of one of the pair). The responsiveness of Go To All is improved.
Previously, results appeared after you stopped typing. In the new experience,
results show as you type.
In contexts requiring enum type completion (for example, assignments to enum
variables, case labels, returning enum type, and so on), the autocompletion list is
now filtered to just the matching enumerators and related constructs.
Added NuGet PackageReference support for C++/CLI MSBuild projects targeting
.NET Core. This change was made to unblock mixed codebases from being able to
adopt .NET Core. This support doesn't work for other C++ project types or any
C++ project types targeting .NET Framework. There are no plans to extend
PackageReference support to other C++ scenarios. The team is working on
separate experiences involving vcpkg for non-MSBuild scenarios and to add
greater functionality.
Added a Serial Monitor window for embedded development, available through
Debug > Windows > Serial Monitor.
Improved C++ indexing by ~66% compared to 17.2.
Updated the version of CMake shipped with Visual Studio to version 3.23. See the
CMake 3.23 release notes for details of what is available.
Upgraded the versions of LLVM tools shipped with Visual Studio to v14. For details
of what is available, see the LLVM and Clang release notes.
Updated the side-by-side Dev 16.11 C++ Toolset to version 14.29.30145.00. The
latest version of the Dev 16.11 C++ Toolset contains important bug fixes, including
fixing all remaining C++20 defect reports. For more information about bug fixes,
including C++20 defect reports in Dev 16.11, see Visual Studio 2019 version
16.11.14 release notes.
Made various improvements to the in-editor experience of C++ modules. We're
continuously working on improving the quality of the experience but encourage
you to try them in 17.3. Report remaining issues through Developer Community .

What's new for C++ in Visual Studio version


17.2
Released May 2022

ノ Expand table

For more information about See

What's new for C++ developers Visual Studio 2022 17.2 is now
available
For more information about See

Standard Library (STL) merged C++20 defect reports, STL Changelog 17.2
C++23 features, LWG issue resolutions, performance
improvements, enhanced behavior, and fixed bugs

New features in the Visual Studio 17.2 IDE Visual Studio 2022 version 17.2
Release Notes

C++ language conformance improvements in Visual C++ Conformance improvements,


Studio 2022 17.2 behavior changes, and bug fixes in
Visual Studio 2022

A partial list of new features in 17.2:

Added compiler support for C++23 feature deducing this , available under the
/std:c++latest option.

Added IntelliSense support for C++23 features deducing this and if consteval .
Added inline parameter name and type hint support, toggled by pressing Alt+F1
or double-tapping Ctrl. This behavior can be customized under Tools > Options >
Text Editors > C/C++ > IntelliSense.
Added experimental support for C++20 modules in CMake projects. This support
is currently only available with the Visual Studio (MSBuild) generator.
In 17.1, we introduced peripheral register and RTOS views for embedded
developers. We continue to improve the capabilities of those views with usability
improvements in 17.2:
The RTOS tool window is now hidden by default. It prevents showing a tool
window with error messages that aren't relevant when you're not using an
RTOS.
When you double-click an RTOS object in the tool window, it adds a watch for
the object.
When you select the start and end values for the stack pointer in the RTOS tool
window, it opens in the memory window.
Added thread awareness for device targets to the call stack window.
Users can now select a pin icon next to peripherals, registers, or fields to pin
them the top of the Peripheral View.
Added implementations of the remaining C++20 defect reports (also known as
backports). All C++20 features are now available under the /std:c++20 option. For
more information about the implemented backports, see the C++20 Defect
Reports project in the Microsoft/STL GitHub repository and the MSVC's STL
Completes /std:c++20 blog post.
We added various C++23 Library features, available under the /std:c++latest
option. For more information about the new features, see the STL Repo
changelog .
Improved performance of the initial C++ indexing by up to 20%, depending on the
depth of the include graph.

What's new for C++ in Visual Studio version


17.1
Released Feb 2022

ノ Expand table

For more information about See

What's new for C++ developers Visual Studio 2022 17.1 is now
available!

Standard Library (STL) merged C++23 features, LWG STL Changelog 17.1
issue resolutions, performance improvements,
enhanced behavior, and fixed bugs

New features in the Visual Studio 17.1 IDE Visual Studio 2022 version 17.1 Release
Notes

C++ language conformance improvements in Visual C++ Conformance improvements,


Studio 2022 17.1 behavior changes, and bug fixes in
Visual Studio 2022

A partial list of new features in 17.1:

A new Configure Preset template is added to configure and build CMake projects
on a remote macOS system with CMakePresets.json . You can also launch CMake
targets on a remote macOS system, and then debug remotely in the Visual Studio
debugger backed by GDB or LLDB.
You can now debug core dumps on a remote macOS system from Visual Studio
with LLDB or GDB.
The versions of Clang and LLVM shipped with Visual Studio are upgraded to
v13.
Visual Studio's CMake integration is only active when a CMakeLists.txt is
identified at the root of the open workspace. If a CMakeLists.txt is identified at
another level of the workspace, then you're prompted to activate Visual Studio's
CMake integration with a notification.
New views that enable you to inspect and interact with peripheral registers on
microcontrollers and real time operating systems (RTOS) objects, available through
Debug > Windows > Embedded Registers
Added a new thread view for RTOS projects, available through Debug > Windows
> RTOS Objects. For more information, see Embedded Software Development in
Visual Studio .

What's new for C++ in Visual Studio version


17.0
Released Nov 2021

ノ Expand table

For more information about See

New features in the Visual Studio 17.0 IDE Visual Studio 2022 version 17.0
Release Notes

Standard Library (STL) merged C++26 and C++23 STL Changelog 17.0
features, C++20 defect reports, LWG issue resolutions,
performance improvements, enhanced behavior, and fixed
bugs

C++ language conformance improvements in Visual C++ Conformance improvements,


Studio 2022 17.0 behavior changes, and bug fixes in
Visual Studio 2022 17.10

An overview of some of the new features in Visual Studio 2022 version 17.0:

The Visual Studio IDE, devenv.exe , is now a native 64-bit application.


The MSVC toolset now defaults to SHA-256 source hashing in debug records.
Previously, the toolset used MD5 for source hashing by default.
The v143 build tools are now available through the Visual Studio installer and in
the standalone build tools .

Hot Reload for native C++


Hot Reload for C++ makes it possible to make many types of code edits to your
running app and apply them without needing to pause app execution with
something like a breakpoint.

In Visual Studio 2022, when you start your app in the debugger, you can use the Hot
Reload button to modify your application while it's still running. This experience is
powered by native Edit and Continue. For more information about supported edits, see
Edit and Continue (C++).

Hot Reload supports CMake and Open Folder projects.

WSL2 support
You can now build and debug natively on WSL2 without establishing an SSH
connection. Both cross-platform CMake projects and MSBuild-based Linux projects
are supported.

Improved CMake support


Upgraded the version of CMake shipped with Visual Studio to version 3.21. For
more information on what's available in this version, see the CMake 3.21 release
notes .

CMake Overview Pages are updated to support CMakePresets.json .

You can now configure and build your CMake projects with CMake 3.21 and
CMakePresets.json v3.

Visual Studio now supports the buildPresets.targets option in


CMakePresets.json . This option allows you to build a subset of targets in your

CMake project.

The Project menu in CMake projects is streamlined and exposes options to "Delete
Cache and Reconfigure" and "View Cache."

Implemented the /scanDependencies compiler option to list C++20 module


dependencies for CMake projects, as described in P1689R5 . It's a step towards
support for building modules-based projects with CMake and we're working on
completing this support in later releases.

Standard Library improvements


Select Standard Library (STL) improvements are highlighted here. For a comprehensive
list of new functionality, changes, bug fixes, and performance improvements, see the STL
team's Changelog .

Added debugging visualizers to improve how the following types are displayed:
source_location , bind_front() , u8string (and its iterators), default_sentinel_t ,
unreachable_sentinel_t , ranges::empty_view , ranges::single_view ,
ranges::iota_view (and its iterator/sentinel), ranges::ref_view , thread ,

thread::id , jthread , and filesystem::path

Added [[nodiscard]] to the stoi() family of functions in <string> and to various


functions in <locale> such as the collate member functions, has_facet() , and
the isalnum() and tolower() families.
P0980R1 Made std::string constexpr in VS 2019 16.10. Now supported for
Clang.
P1004R2 Made std::vector constexpr in VS 2019 16.10. Now supported for
Clang.

Highlighted C++23 features

P1048R1 Added is_scoped_enum , a new trait for the C++ Standard library, which
detects whether a type is a scoped enumeration.
P1132R7 out_ptr() , inout_ptr()

P1679R3 contains() For basic_string and basic_string_view

P1682R3 to_underlying() for enumerations

P2162R2 Allow inheriting from std::variant


P2166R1 Prohibit constructing basic_string and basic_string_view from
nullptr . This change is a source-breaking change. Code that previously had

undefined behavior at runtime is now rejected with compiler errors.


P2186R2 Removed garbage collection support. This change removes
declare_reachable , undeclare_reachable , declare_no_pointers ,

undeclare_no_pointers , get_pointer_safety . Previously, these functions had no

effect.

Highlighted performance improvements

<format> now detects when it's writing to a back_insert_iterator for a

basic_string or a vector , and makes a faster call to insert() at the end() of the

container.
We improved the performance of std::find() and std::count() for vector<bool>
19x and 26x (times, not percent).
We improved the performance of std::count() for vector<bool>
std::byte now has the same performance as unsigned char in reverse() and

variant::swap()

Clang and LLVM support


LLVM tools shipped with Visual Studio are upgraded to LLVM 12. For more
information, see the LLVM release notes .

Clang-cl support was updated to LLVM 12.

You can now debug processes running on a remote system from Visual Studio by
using LLDB.

C++ AMP deprecated


C++ AMP headers are now deprecated. Including <amp.h> in a C++ project
generates build errors. To silence the errors, define
_SILENCE_AMP_DEPRECATION_WARNINGS . For more information, see our AMP

Deprecation links.

IntelliSense improvements
We made improvements in C++ IntelliSense when providing navigation and syntax
highlighting for types from imported Modules and Header Units. IntelliSense is an
active area of investment for us. Help us improve: Share your feedback on
Developer Community by using Help > Send Feedback.
We improved C++ IntelliSense performance by optimizing cached header usage
and symbol database access, providing improved load times to get into your code.
The IntelliSense Code Linter for C++ is now on by default, providing instant as-
you-type suggestions and fix suggestions for common code defects.
C++ IntelliSense for CMake projects now works when using a preset with a display
name.

C++ Workload updates


Updated to NDK r21 LTS in the C++ Mobile Development workload.
The Game development with C++ workload now installs the latest Unreal Engine
with support for Visual Studio 2022.

Code analysis improvements


Code analysis now enforces that return values of functions annotated with
_Check_return_ or _Must_inspect_result_ must be checked.

Null pointer dereference detection is improved in our code analysis tooling.


Added support for gsl::not_null to code analysis.
Support for Libfuzzer under the /fsanitize=fuzzer compiler option.
Release notes for older versions
Release notes for older C++ versions are also available:

For information on what's new for C++ in Visual Studio 2019, see What's new for
C++ in Visual Studio 2019.
For information on what's new for C++ in Visual Studio 2017, see What's new for
C++ in Visual Studio 2017.
For information on what's new in earlier versions, see Visual C++ What's new 2003
through 2015.

Known issues
C++ IntelliSense

When importing a C++20 module or header unit, IntelliSense may stop working or
'There are too many errors' error is shown .

For more information on other open issues and available workarounds for C++ in Visual
Studio 2022, see the C++ Developer Community issues list .

Feedback and suggestions


We'd love to hear from you! You can Report a Problem or Suggest a Feature by using
the Send Feedback icon in the upper right-hand corner of either the installer or the
Visual Studio IDE, or from Help > Send Feedback. You can track your issues by using
Visual Studio Developer Community , where you add comments or find solutions. You
can also get free installation help through our Live Chat support .

Blogs
Take advantage of the insights and recommendations available in the Microsoft
Developer Blogs site to stay up to date on all new releases. The blogs include deep
dive posts on a broad range of features. The C++ Team Blog and the Visual Studio
Blog are of particular interest.

) Note: The author created this article with assistance from AI. Learn more

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


What's new for C++ in Visual Studio
2019
Article • 10/17/2022

Visual Studio 2019 brings many updates and fixes to the Microsoft C++ environment.
We've fixed many bugs and issues in the compiler and tools. Many of these issues were
submitted by customers through the Report a Problem and Provide a Suggestion
options under Send Feedback. Thank you for reporting bugs!

For more information on what's new in all of Visual Studio, visit What's new in Visual
Studio 2019. For information on what's new for C++ in Visual Studio 2017, see What's
new for C++ in Visual Studio 2017. For information on what's new for C++ in Visual
Studio 2015 and earlier versions, see Visual C++ What's New 2003 through 2015. For
more information, see Microsoft C++ docs: What's new.

What's new for C++ in Visual Studio version


16.11
For a summary of new features and bug fixes in Visual Studio version 16.11, see What's
New in Visual Studio 2019 version 16.11.

The compiler now supports the /std:c++20 compiler mode. Previously, C++20
features were available only in /std:c++latest mode in Visual Studio 2019. Features
that originally required /std:c++latest mode now work in /std:c++20 mode or
later in the latest versions of Visual Studio.

LLVM tools shipped with Visual Studio have been upgraded to LLVM 12. For
details, see the LLVM release notes .

Clang-cl support was updated to LLVM 12.

What's new for C++ in Visual Studio version


16.10
For a summary of new features and bug fixes in Visual Studio version 16.10, see What's
New in Visual Studio 2019 version 16.10.

All C++20 features are now available under /std:c++latest. While MSVC's
implementation of the C++20 standards (as currently published by ISO) is feature
complete, some key C++20 library features are expected to be amended by
upcoming Defect Reports (ISO C++20 bug fixes) that may change them in an ABI-
incompatible way. Please see Microsoft/STL Issue #1814 for more details.
C++20 immediate functions & constinit support added in 16.10
The final pieces of <chrono> : new clocks, leap seconds, time zones, and parsing
Implementation of <format> for text formatting

/openmp:llvm is now available on x86 and ARM64, in addition to x64

Include directories can now be designated as external with customized compilation


warning levels and code analysis settings.

Added the /await:strict option to enable C++20-style coroutines in earlier


language modes.

Debugger visualization of std::coroutine_handle<T> now displays the original


coroutine function name and signature and the current suspend point.

Added support for CMakePresets .

You're now required to accept or deny the host key fingerprint presented by the
server when adding a new remote connection in Visual Studio.

Added an /external switch to MSVC for specifying headers which should be treated
as external for warning purposes.

What's new for C++ in Visual Studio version


16.9
For a summary of new features and bug fixes in Visual Studio version 16.9, see What's
New in Visual Studio 2019 version 16.9.

Address Sanitizer:

Our address sanitizer support on Windows is out of experimental mode and has
reached general availability.

Expanded RtlAllocateHeap support, fixed a compatibility issue with


RtlCreateHeap and RtlAllocateHeap interceptors when creating executable

memory pools.

Added support for the legacy GlobalAlloc and LocalAlloc family of memory
functions. You can enable these interceptors by setting the environment flag
ASAN_OPTIONS=windows_hook_legacy_allocators=true .

Updated error messages for shadow memory interleaving and interception


failure to make problems and resolutions explicit.

The IDE integration can now handle the complete collection of exceptions which
ASan can report.

The compiler and linker will suggest emitting debug information if they detect
you're building with ASan but not emitting debug information.

You can now target the LLVM version of the OpenMP runtime with the new CL
switch /openmp:llvm . This adds support for the lastprivate clause on #pragma omp
sections and unsigned index variables in parallel for loops. The /openmp:llvm
switch is currently only available for the amd64 target and is still experimental.

Visual Studio CMake projects now have first-class support for remote Windows
development. This includes configuring a CMake project to target Windows
ARM64, deploying the project to a remote Windows machine, and debugging the
project on a remote Windows machine from Visual Studio.

The version of Ninja shipped with Visual Studio on Windows has been updated to
version 1.10. For more information on what's included, see the Ninja 1.10 release
notes .

The version of CMake shipped with Visual Studio has been updated to version
3.19. For more information on what's included, see the CMake 3.19 release
notes .

Marked many lock/guard types in the STL as nodiscard .

IntelliSense:

Improved the stability and functionality of providing imported modules and


header units completion in IntelliSense.

Added Go-to-definition on module imports, indexing support for export {...} ,


and more accurate module reference for modules with the same name.

Improved the language conformance of C++ IntelliSense by adding support for


Copy-initialization of temporary in reference direct-initialization ,
__builtin_memcpy and __builtin_memmove , Fixing inconsistencies between

constexpr and consteval functions , Lifetime-extended temporaries in constant


expressions , and Similar types and reference binding .
Added completion for make_unique, make_shared, emplace and emplace_back
which provides completion based on the type parameter specified.

MSVC now determines the correct address sanitizer runtimes required for your
binaries. Your Visual Studio project will automatically get the new changes. When
using address sanitizer on the command line, you now only need to pass
/fsanitize=address to the compiler.

Visual Studio's Connection Manager now supports private keys using the ECDSA
public key algorithm.

Updated the versions of LLVM and Clang shipped in our installer to v11. Read the
release notes for LLVM and Clang for more information.

Visual Studio will now use CMake variables from toolchain files to configure
IntelliSense. This will provide a better experience for embedded and Android
development.

Implementation of the More Constexpr Containers proposal , which allows


destructors and new expressions to be constexpr . This paves the way for utilities
like constexpr std::vector and std::string .

Extended support for C++20 modules IntelliSense, including Go To Definition, Go


To Module, and member completion.

Abbreviated function templates are now supported in the MSVC compiler.

What's new for C++ in Visual Studio version


16.8
For a summary of new features and bug fixes in Visual Studio version 16.8, see What's
New in Visual Studio 2019 version 16.8.

C++20 Coroutines are now supported under /std:c++latest (or /std:c++20 starting
in Visual Studio 2019 version 16.11) and the <coroutine> header.

IntelliSense now provides support for C++20 <concepts> and <ranges> headers,
and rename and browsing for concept definitions.

Our STL now has support for the majority of C++20 Ranges.

Conditionally trivial special member functions are now supported in MSVC.

C11 and C17 are now supported under the /std:c11 and /std:c17 switches.
Additional STL improvements include full support for std::atomic_ref ,
std::midpoint and std::lerp and std::execution::unseq , optimizations for
std::reverse_copy, and more.

Upgraded version of CMake shipped with Visual Studio to CMake 3.18 .

Our code analysis tools now support the SARIF 2.1 standard: the industry standard
static analysis log format.

Missing build tools in Linux projects will now issue a warning in the toolbar and a
clear description of the missing tools in the error list.

You can now debug Linux core dumps on a remote Linux system or WSL directly
from Visual Studio.

For C++ Doxygen comment generation, we added additional comment style


options ( /*! and //! ).

Additional vcpkg announcements .

Compiler support for lambdas in unevaluated contexts.

/DEBUG:FULL link performance improved by multi-threading PDB creation. Several


large applications and AAA games see between 2 to 4 times faster linking.

The Visual Studio debugger now has support for char8_t .

Support for ARM64 projects using clang-cl.

Intel AMX intrinsics support.

What's new for C++ in Visual Studio version


16.7
For a summary of new features and bug fixes in Visual Studio version 16.7, see What's
New in Visual Studio 2019 version 16.7.

Our remote C++ support now supports a wider range of Linux distros and shells,
including sh, csh, bash, tsch, ksh, zsh, and dash. You can override the choice of a
shell for a remote connection by modifying the new "shell" property via
ConnectionManager.exe. This support has been tested with both MSBuild-based
Linux projects and CMake projects targeting a remote Linux system or WSL.
You can now use Ninja (a build system that evaluates incremental builds very
quickly) to improve incremental build times for MSBuild-based Linux projects. You
can opt into this feature by setting "Enable Incremental Build" to "With Ninja" in
the General Property Page. Ninja (ninja-build) must be installed on your remote
Linux system or WSL.

New C++20 Standard Library features have been implemented. Please refer to
the STL Changelog on GitHub for a detailed list.

You can now edit and set default remote SSH connections in the Connection
Manager. This means you can edit an existing remote connection (for example, if
its IP address changed) and set default connections to be consumed in
CMakeSettings.json and launch.vs.json. Remote SSH connections allow you to
build and debug C++ projects on a remote Linux system directly from Visual
Studio.

Enhanced IntelliSense support for Clang on Windows (clang-cl) in Visual Studio.


The clang include path now includes the clang libraries, we've improved in-editor
squiggle display when using the std library, and we've added support for C++2a in
clang mode.

You can now try out underlining code errors and see more suggested quick fixes in
C++ projects. Enable this feature under Tools > Options > Text Editor > C/C++
> Experimental. Set Disable Experimental Code Linter to false. Learn more on the
C++ Team Blog .

We've added four new code analysis rules to incorporate additional safety features
into C++: C26817, C26818, C26819, and C26820.

We've added first-class support for debugging CMake projects on remote systems
with gdbserver.

Find memory corruption errors easily with an experimental implementation of


AddressSanitizer for C++ in Visual Studio, now available for x64 native projects. We
also now support the use of debug runtimes ( /MTd , /MDd , /LDd ).

IntelliSense now has basic support for Concepts, designated initializers, and several
other C++20 features.

.ixx and .cppm files are now recognized as C++ and get treated as such by the

syntax highlighter and IntelliSense.


What's new for C++ in Visual Studio version
16.6
For a summary of new features and bug fixes in Visual Studio version 16.6, see What's
New in Visual Studio 2019 version 16.6.

Improved Doxygen/XML comment generation: Automatically generate Doxygen


or XML doc comment stubs by typing /// or /** above functions. These are now
displayed in Quick Info tooltips as well.

Ninja support for CMake for Linux/WSL: Use Ninja as the underlying generator
when building CMake projects on WSL or a remote system. Ninja is now the
default generator when adding a new Linux or WSL configuration.

Debug templates for remote CMake debugging: We've simplified the templates
for debugging CMake projects on a remote Linux system or WSL with gdb.

Initial support for C++20 concepts: IntelliSense now recognizes C++20


concepts and suggests them in the member list.

What's new for C++ in Visual Studio version


16.5
For a summary of new features and bug fixes in Visual Studio version 16.5, see What's
New in Visual Studio 2019 version 16.5.

IntelliCode Team Completions model and member variables support: C++


developers can now train IntelliCode models on their own codebases. We call this a
Team Completions model because you benefit from your team's practices.
Additionally, we've improved IntelliCode suggestions for member variables.

IntelliSense improvements:
IntelliSense now displays more readable type names when dealing with the
Standard Library.
We've added the ability to toggle whether Enter, Space, and Tab function as
commit characters, and to toggle whether Tab is used to Insert Snippet. Find
these settings under Tools > Options > Text Editor > C/C++ > Advanced >
IntelliSense.

Connection Manager over the command line: You can now interact with your
stored remote connections over the command line. It's useful for tasks such as
provisioning a new development machine or setting up Visual Studio in continuous
integration.

Debug and deploy for WSL: Use Visual Studio's native support for WSL to
separate your build system from your remote deploy system. Now you can build
natively on WSL and deploy the build artifacts to a second remote system for
debugging. This workflow is supported by both CMake projects and MSBuild-
based Linux projects.

Support for FIPS 140-2 compliance mode: Visual Studio now supports FIPS 140-2
compliance mode when developing C++ applications that target a remote Linux
system.

Language services for CMake Language files and better CMake project
manipulation:

The source file copy for CMake projects targeting a remote Linux system has
been optimized. Visual Studio now keeps a "fingerprint file" of the last set of
sources copied remotely and optimizes behavior based on the number of files
that have changed.

Code navigation features such as Go To Definition and Find All References are
now supported for functions, variables, and targets in CMake script files.

Add, remove, and rename source files and targets in your CMake projects from
the IDE without manually editing your CMake scripts. When you add or remove
files with the Solution Explorer, Visual Studio will automatically edit your CMake
project. You can also add, remove, and rename the project's targets from the
Solution Explorer's Targets View.

Linux project improvements: Visual Studio Linux projects now have more accurate
IntelliSense and allow you to control remote header synchronization on a project-
by-project basis.

What's new for C++ in Visual Studio version


16.4
For a summary of new features and bug fixes in Visual Studio version 16.4, see What's
New in Visual Studio 2019 version 16.4.

Code Analysis now natively supports Clang-Tidy for both MSBuild and CMake
projects, whether you're using a Clang or MSVC toolset. clang-tidy checks can run
as part of background code analysis, appear as in-editor warnings (squiggles), and
display in the Error List.

Visual Studio CMake projects now have Overview Pages to help you get started
with cross-platform development. These pages are dynamic and help you connect
to a Linux system and add a Linux or WSL configuration to your CMake project.

The launch dropdown menu for CMake projects now displays your most recently
used targets and can be filtered.

C++/CLI now supports interop with .NET Core 3.1 and higher on Windows.

You can now enable ASan for projects compiled with MSVC on Windows for
runtime instrumentation of C++ code that helps with detection of memory errors.

Updates to MSVC's C++ Standard Library:


C++17: Implemented to_chars() general precision,
completing P0067R5 Elementary String Conversions (charconv). This
completes implementation of all library features in the C++17 Standard.
C++20: Implemented P1754R1 Rename concepts to standard_case. To include
these features, use the /std:c++latest compiler option (or /std:c++20 starting
in Visual Studio 2019 version 16.11). The option can also be set in the
Configuration Properties > C/C++ > Language project property page using
the C++ Language Standard property.

A new collection of tools named C++ Build Insights is now available. For more
information about the announcement, see the C++ Team Blog .

What's new for C++ in Visual Studio version


16.3
For a summary of new features and bug fixes in Visual Studio version 16.3, see What's
New in Visual Studio 2019 version 16.3.

C++ developers can now toggle line comments using the keyboard shortcut
Ctrl+K, Ctrl+/.

IntelliSense member lists are now filtered based on type qualifiers, for example,
const std::vector now filters out methods such as push_back .

We added these C++20 Standard Library features (available under /std:c++latest ,


or /std:c++20 starting in Visual Studio 2019 version 16.11):
P0487R1 : Fixing operator>>(basic_istream&, CharT*)
P0616R0 : Using move() In <numeric>
P0758R1 : is_nothrow_convertible
P0734R0 : C++ extensions for Concepts
P0898R3 : Standard Library Concepts
P0919R3 : Heterogeneous Lookup For Unordered Containers

New C++ Core Guideline checks , including the new "Enum Rules" rule set, and
additional const , enum , and type rules.

A new default semantic colorization scheme allows users to better understand


their code at a glance, the call-stack window can be configured to hide template
arguments, and C++ IntelliCode is on-by-default.

Configure debug targets and custom tasks with environment variables using
CMakeSettings.json or CppProperties.json or the new "env" tag on individual
targets and tasks in launch.vs.json and tasks.vs.json.

Users can now use a quick action on missing vcpkg packages to automatically
open a console and install to the default vcpkg installation.

The remote header copy done by Linux projects (CMake and MSBuild) has been
optimized and now runs in parallel.

Visual Studio's native support for WSL now supports parallel builds for MSBuild-
based Linux projects.

Users can now specify a list of local build outputs to deploy to a remote system
with Linux Makefile projects.

Setting descriptions in the CMake Settings Editor now contain more context and
links to helpful documentation.

The C++ base model for IntelliCode is now enabled by default. You can change
this setting by going to Tools > Options > IntelliCode.

What's new for C++ in Visual Studio version


16.2
For a summary of new features and bug fixes in Visual Studio version 16.2, see What's
New in Visual Studio 2019 version 16.2.

For local CMake projects configured with Clang, Code Analysis now runs clang-tidy
checks, appearing as part of background code analysis as in-editor warnings
(squiggles) and in the Error List.

Updated the <charconv> header for C++17's P0067R5 Elementary string


conversions:
Added floating-point to_chars() overloads for chars_format::fixed and
chars_format::scientific precision ( chars_format::general precision is the

only part not yet implemented)


Optimized chars_format::fixed shortest

Added these C++20 Standard Library features:


Available under /std:c++latest (or /std:c++20 starting in Visual Studio 2019
version 16.11):
P0020R6 : atomic<floating-point>
P0463R1 : endian enumeration
P0482R6 : char8_t type for UTF-8 characters and strings
P0653R2 : to_address() for converting a pointer to a raw pointer
Available under /std:c++17 and /std:c++latest (or /std:c++20 starting in
Visual Studio 2019 version 16.11):
P0600R1 : [[nodiscard]] in the library
Available unconditionally:
P0754R2 : <version> header
P0771R1 : std::function move constructor should be noexcept

Windows SDK is no longer a dependency for the CMake for Windows and CMake
for Linux components.

Improvements to the C++ linker to significantly improve iteration build times for
the largest of input. /DEBUG:FAST and /INCREMENTAL times are on average twice as
fast, and /DEBUG:FULL is now three to six times faster.

What's new for C++ in Visual Studio version


16.1
For a summary of new features and bug fixes in Visual Studio version 16.1, see What's
New in Visual Studio 2019 version 16.1.

C++ compiler
These C++20 features have been implemented in the C++ compiler, available
under /std:c++latest (or /std:c++20 starting in Visual Studio 2019 version 16.11):
Increased ability to find function templates via argument-dependent lookup for
function call expressions with explicit template arguments (P0846R0 ).
Designated initialization (P0329R4 ), which allows specific members to be
selected in aggregate initialization, for example, by using the Type t { .member
= expr } syntax.

Lambda support has been overhauled, addressing a large number of long-


standing bugs. This change is enabled by default when using /std:c++20 or
/std:c++latest . In /std:c++17 language mode and under the default ( /std:c++14

) mode, the new parser can be enabled by using /Zc:lambda in Visual Studio 2019
version 16.9 or later (previously available as /experimental:newLambdaProcessor
beginning in Visual Studio 2019 version 16.3), for example, /std:c++17 /Zc:lambda .

C++ standard library improvements


These C++20 features have been added to our implementation of the C++
Standard Library, available under /std:c++latest :
starts_with and ends_with for basic_string and basic_string_view .

contains for associative containers.


remove , remove_if , and unique for list and forward_list now return

size_type .

shift_left and shift_right added to <algorithm> .

C++ IDE

IntelliCode for C++

IntelliCode now ships as an optional component in the Desktop Development with C++
workload. For more information, see Improved C++ IntelliCode now Ships with Visual
Studio 2019 .

IntelliCode uses its own extensive training and your code context to put what you're
most likely to use at the top of your completion list. It can often eliminate the need to
scroll down through the list. For C++, IntelliCode offers the most help when using
popular libraries such as the standard library.

The new IntelliCode features (Custom Models, C++ support, and EditorConfig inference)
are disabled by default. To enable them, go to Tools > Options > IntelliCode > General.
This version of IntelliCode has improved accuracy and includes support for free-
functions. For more information, see AI-Assisted Code Completion Suggestions Come to
C++ via IntelliCode .

Quick Info improvements

The Quick Info tooltip now respects the semantic colorization of your editor. It also
has a new Search Online link that will search online documentation for information
about the hovered code construct. The link provided by Quick Info for red-
squiggled code will search for the error online. That way you don't need to retype
the message into your browser. For more information, see Quick Info
Improvements in Visual Studio 2019: Colorization and Search Online .

General improvements

The Template Bar can populate the dropdown menu based on instantiations of
that template in your codebase.

Lightbulbs for missing #include directives that vcpkg can install, and
autocompletion of available packages for the CMake find_package directive.

The General Property Page for C++ projects has been revised. Some options are
now listed under a new Advanced page. The Advanced page also includes new
properties for your preferred toolset architecture, debug libraries, the MSVC
toolset minor version, and Unity (jumbo) builds.

CMake support
We updated the CMake version that ships with Visual Studio to 3.14. This version
adds built-in support for MSBuild generators targeting Visual Studio 2019 projects
as well as file-based IDE integration APIs.

We've added improvements to the CMake Settings Editor, including support for
Windows Subsystem for Linux (WSL) and configurations from existing caches,
changes to the default build and install roots, and support for environment
variables in Linux CMake configurations.

Completions and quick info for built-in CMake commands, variables, and
properties make it easier to edit your CMakeLists.txt files.

We've integrated support for editing, building, and debugging CMake projects
with Clang/LLVM. For more information, see Clang/LLVM Support in Visual
Studio .
Linux and the Windows Subsystem for Linux
We now support AddressSanitizer (ASan) in Linux and CMake cross-platform
projects. For more information, see AddressSanitizer (ASan) for the Linux Workload
in Visual Studio 2019 .

We've integrated Visual Studio support for using C++ with the Windows
Subsystem for Linux (WSL). Now you can use your local Windows Subsystem for
Linux (WSL) installation with C++ natively in Visual Studio without additional
configuration or a SSH connection. For more information, see C++ with Visual
Studio 2019 and Windows Subsystem for Linux (WSL) .

Code Analysis
New quick fixes for uninitialized variable checks were added. Code Analysis
warnings C6001: using uninitialized memory <variable> and C26494
VAR_USE_BEFORE_INIT are available in the lightbulb menu on relevant lines.
They're enabled by default in the Microsoft Native Minimum ruleset and C++ Core
Check Type rulesets, respectively. For more information, see New code analysis
quick fixes for uninitialized memory (C6001) and use before init (C26494)
warnings .

Remote builds
Users can now separate remote build machines from remote debug machines
when targeting Linux in both MSBuild and CMake projects.

The improved logging for remote connections makes it easier to diagnose issues in
cross-platform development.

What's new for C++ in Visual Studio version


16.0
For a summary of new features and bug fixes in Visual Studio version 16.0, see What's
New in Visual Studio 2019 version 16.0.

C++ compiler
Enhanced support for C++17 features and correctness fixes, plus experimental
support for C++20 features such as modules and coroutines. For detailed
information, see C++ Conformance Improvements in Visual Studio 2019.

The /std:c++latest option now includes C++20 features that aren't necessarily
complete, including initial support for the C++20 operator <=> ("spaceship") for
three-way comparison.

The C++ compiler switch /Gm is now deprecated. Consider disabling the /Gm
switch in your build scripts if it's explicitly defined. However, you can also safely
ignore the deprecation warning for /Gm , because it's not treated as an error when
using "Treat warnings as errors" (/WX).

As MSVC begins implementing features from the C++20 standard draft under the
/std:c++latest flag, /std:c++latest is now incompatible with /clr (all flavors),

/ZW , and /Gm . In Visual Studio 2019, use /std:c++17 or /std:c++14 modes when

compiling with /clr , /ZW , or /Gm (but see previous bullet).

Precompiled headers are no longer generated by default for C++ console and
desktop apps.

Codegen, security, diagnostics, and versioning

Improved analysis with /Qspectre for providing mitigation assistance for Spectre Variant
1 (CVE-2017-5753 ). For more information, see Spectre Mitigations in MSVC .

C++ standard library improvements


Implementation of additional C++17 and C++20 library features and correctness
fixes. For detailed information, see C++ Conformance Improvements in Visual
Studio 2019.

Clang-Format has been applied to the C++ standard library headers for improved
readability.

Because Visual Studio now supports Just My Code for C++, the standard library no
longer needs to provide custom machinery for std::function and std::visit to
achieve the same effect. Removing that machinery largely has no user-visible
effects. One exception is that the compiler will no longer produce diagnostics that
indicate issues on line 15732480 or 16707566 of <type_traits> or <variant> .

Performance/throughput improvements in the compiler


and standard library
Build throughput improvements, including the way the linker handles File I/O, and
link time in PDB type merging and creation.

Added basic support for OpenMP SIMD vectorization. You can enable it using the
new compiler switch /openmp:experimental . This option allows loops annotated
with #pragma omp simd to potentially be vectorized. The vectorization isn't
guaranteed, and loops annotated but not vectorized will get a warning reported.
No SIMD clauses are supported; they're ignored, and a warning is reported.

Added a new inlining command-line switch /Ob3 , which is a more aggressive


version of /Ob2 . /O2 (optimize the binary for speed) still implies /Ob2 by default. If
you find that the compiler doesn't inline aggressively enough, consider passing
/O2 -Ob3 .

We've added support for Short Vector Math Library (SVML) intrinsic functions.
These functions compute the 128-bit, 256-bit, or 512-bit vector equivalents. We
added them to support hand vectorization of loops with calls to math library
functions, and certain other operations like integer division. See the Intel Intrinsic
Guide for definitions of the supported functions.

New and improved optimizations:

Constant-folding and arithmetic simplifications for expressions using SIMD


vector intrinsics, for both float and integer forms.

A more powerful analysis for extracting information from control flow


(if/else/switch statements) to remove branches always proven to be true or
false.

Improved memset unrolling to use SSE2 vector instructions.

Improved removal of useless struct/class copies, especially for C++ programs


that pass by value.

Improved optimization of code using memmove , such as std::copy or


std::vector and std::string construction.

Optimized the standard library physical design to avoid compiling parts of the
standard library not directly included. This change cut the build time of an empty
file that includes only <vector> in half. As a consequence, you may need to add
#include directives for headers that were previously indirectly included. For

example, code that uses std::out_of_range may now need to add #include
<stdexcept> . Code that uses a stream insertion operator may now need to add
#include <ostream> . The benefit is that only translation units actually using
<stdexcept> or <ostream> components pay the throughput cost to compile them.

if constexpr was applied in more places in the standard library for improved

throughput and reduced code size in copy operations, in permutations like reverse
and rotate, and in the parallel algorithms library.

The standard library now internally uses if constexpr to reduce compile times,
even in C++14 mode.

The runtime dynamic linking detection for the parallel algorithms library no longer
uses an entire page to store the function pointer array. Marking this memory read-
only was considered no longer relevant for security purposes.

The std::thread constructor no longer waits for the thread to start, and no longer
inserts so many layers of function calls between the underlying C library
_beginthreadex and the supplied callable object. Previously std::thread put six

functions between _beginthreadex and the supplied callable object. This number
has been reduced to only three, two of which are just std::invoke . This change
also resolves an obscure timing bug, where a std::thread constructor would stop
responding if the system clock changed at the exact moment the std::thread was
being created.

Fixed a performance regression in std::hash that we introduced when


implementing std::hash<std::filesystem::path> .

The standard library now uses destructors instead of catch blocks in several places
to achieve correctness. This change results in better debugger interaction:
Exceptions you throw through the standard library in the affected locations now
show up as being thrown from their original throw site, rather than our rethrow.
Not all standard library catch blocks were eliminated. We expect the number of
catch blocks to be reduced in later releases of MSVC.

Suboptimal codegen in std::bitset caused by a conditional throw inside a


noexcept function was fixed by factoring out the throwing path.

The std::list and std::unordered_* family use non-debugging iterators


internally in more places.

Several std::list members were changed to reuse list nodes where possible
rather than deallocating and reallocating them. For example, given a list<int>
that already has a size of 3, a call to assign(4, 1729) now overwrites the int
values in the first three list nodes, and allocates one new list node with the value
1729.

All standard library calls to erase(begin(), end()) were changed to clear() .

std::vector now initializes and erases elements more efficiently in certain cases.

Improvements to std::variant to make it more optimizer-friendly, resulting in


better generated code. Code inlining is now much better with std::visit .

C++ IDE

Live Share C++ support

Live Share now supports C++, allowing developers using Visual Studio or Visual Studio
Code to collaborate in real time. For more information, see Announcing Live Share for
C++: Real-Time Sharing and Collaboration

Template IntelliSense
The Template Bar now uses the Peek Window UI rather than a modal window, supports
nested templates, and pre-populates any default arguments into the Peek Window. For
more information, see Template IntelliSense Improvements for Visual Studio 2019
Preview 2 . A Most Recently Used dropdown in the Template Bar enables you to
quickly switch between previous sets of sample arguments.

New Start window experience

When launching the IDE, a new Start window appears. It has options to open recent
projects, clone code from source control, open local code as a solution or a folder, or
create a new project. The New Project dialog has also been overhauled into a search-
first, filterable experience.

New names for some project templates

We've modified several project template names and descriptions to fit with the updated
New Project dialog.

Various productivity improvements


Visual Studio 2019 includes the following features that will help make coding easier and
more intuitive:

Quick fixes for:


Add missing #include
NULL to nullptr

Add missing semicolon


Resolve missing namespace or scope
Replace bad indirection operands ( * to & and & to * )
Quick Info for a block by hovering on closing brace
Peek Header / Code File
Go to Definition on #include opens the file

For more information, see C++ Productivity Improvements in Visual Studio 2019 Preview
2 .

CMake support
Support for CMake 3.14

Visual Studio can now open existing CMake caches generated by external tools,
such as CMakeGUI, customized meta-build systems or build scripts that invoke
cmake.exe themselves.

Improved IntelliSense performance.

A new settings editor provides an alternative to manually editing the


CMakeSettings.json file, and provides some parity with CMakeGUI.

Visual Studio helps bootstrap your C++ development with CMake on Linux by
detecting if you have a compatible version of CMake on your Linux machine. If not,
it offers to install it for you.

Incompatible settings in CMakeSettings, such as mismatched architectures or


incompatible CMake generator settings, show squiggles in the JSON editor and
errors in the error list.

The vcpkg toolchain is automatically detected and enabled for CMake projects that
are opened in the IDE once vcpkg integrate install has been run. This behavior
can be turned off by specifying an empty toolchain file in CMakeSettings.

CMake projects now enable Just My Code debugging by default.


Static analysis warnings are now processed in the background and displayed in the
editor for CMake projects.

Clearer build and configure 'begin' and 'end' messages for CMake projects and
support for Visual Studio's build progress UI. Additionally, there's now a CMake
verbosity setting in Tools > Options to customize the detail level of CMake build
and configuration messages in the Output Window.

The cmakeToolchain setting is now supported in CMakeSettings.json to specify


toolchains without manually modifying the CMake command line.

A new Build All menu shortcut Ctrl+Shift+B.

IncrediBuild integration
IncrediBuild is included as an optional component in the Desktop development with
C++ workload. The IncrediBuild Build Monitor is fully integrated in the Visual Studio IDE.
For more information, see Visualize your build with IncrediBuild's Build Monitor and
Visual Studio 2019 .

Debugging
For C++ applications running on Windows, PDB files now load in a separate 64-bit
process. This change addresses a range of crashes caused by the debugger
running out of memory. For example, when debugging applications that contain a
large number of modules and PDB files.

Search is enabled in the Watch, Autos, and Locals windows.

Windows desktop development with C++


These C++ ATL/MFC wizards are no longer available:
ATL COM+ 1.0 Component Wizard
ATL Active Server Pages Component Wizard
ATL OLE DB Provider Wizard
ATL Property Page Wizard
ATL OLE DB Consumer Wizard
MFC ODBC Consumer
MFC class from ActiveX control
MFC class from Type Lib.
Sample code for these technologies is archived in Microsoft Learn and the
VCSamples GitHub repository.

The Windows 8.1 Software Development Kit (SDK) is no longer available in the
Visual Studio installer. We recommend you upgrade your C++ projects to the
latest Windows SDK. If you have a hard dependency on 8.1, you can download it
from the Windows SDK archive.

Windows XP targeting will no longer be available for the latest C++ toolset. XP
targeting with VS 2017-level MSVC compiler & libraries is still supported and can
be installed via "Individual components."

Our documentation actively discourages usage of Merge Modules for Visual C++
Runtime deployment. We're taking the extra step this release of marking our
MSMs as deprecated. Consider migrating your VCRuntime central deployment
from MSMs to the redistributable package.

Mobile development with C++ (Android and iOS)


The C++ Android experience now defaults to Android SDK 25 and Android NDK 16b.

Clang/C2 platform toolset


The Clang/C2 experimental component has been removed. Use the MSVC toolset for full
C++ standards conformance with /permissive- and /std:c++17 , or the Clang/LLVM
toolchain for Windows.

Code analysis
Code analysis now runs automatically in the background. Warnings display as
green squiggles in-editor as you type. For more information, see In-editor code
analysis in Visual Studio 2019 Preview 2 .

New experimental ConcurrencyCheck rules for well-known standard library types


from the <mutex> header. For more information, see Concurrency Code Analysis in
Visual Studio 2019 .

An updated partial implementation of the Lifetime profile checker , which detects


dangling pointers and references. For more information, see Lifetime Profile
Update in Visual Studio 2019 Preview 2 .
More coroutine-related checks, including C26138, C26810, C26811, and the
experimental rule C26800. For more information, see New Code Analysis Checks in
Visual Studio 2019: use-after-move and coroutine .

Unit testing
The Managed C++ Test Project template is no longer available. You can continue using
the Managed C++ Test framework in your existing projects. For new unit tests, consider
using one of the native test frameworks for which Visual Studio provides templates
(MSTest, Google Test), or the Managed C# Test Project template.
What's new for C++ in Visual Studio
2017
Article • 10/25/2021

Visual Studio 2017 brings many updates and fixes to the C++ environment. We've fixed
over 250 bugs and reported issues in the compiler and tools. Many were submitted by
customers through the Report a Problem and Provide a Suggestion options under Send
Feedback. Thank you for reporting bugs!

For more information on what's new in all of Visual Studio, see What's new in Visual
Studio 2017. For information on what's new for C++ in Visual Studio 2019, see What's
new for C++ in Visual Studio 2019. For information on what's new for C++ in Visual
Studio 2015 and earlier versions, see Visual C++ What's New 2003 through 2015. For
information about what's new in the C++ docs, see Microsoft C++ docs: What's new.

Visual Studio 2017 C++ compiler

C++ conformance improvements


We've updated the C++ compiler and standard library in this release with enhanced
support for C++11 and C++14 features. It also includes preliminary support for certain
features expected to be in the C++17 standard. For detailed information, see C++
Conformance Improvements in Visual Studio 2017.

Visual Studio 2017 version 15.5

The compiler supports about 75% of the features that are new in C++17, including
structured bindings, constexpr lambdas, if constexpr , inline variables, fold expressions,
and adding noexcept to the type system. These features are available under the
/std:c++17 option. For more information, see C++ Conformance Improvements in
Visual Studio 2017

Visual Studio 2017 version 15.7

The MSVC compiler toolset in Visual Studio version 15.7 now conforms with the C++
Standard. For more information, see Announcing: MSVC Conforms to the C++
Standard and Microsoft C/C++ language conformance.
Visual Studio 2017 version 15.8

The /experimental:preprocessor compiler switch enables the new experimental MSVC


preprocessor that will eventually conform to all applicable C and C++ standards. For
more information, see MSVC new preprocessor overview.

New compiler options


/permissive-: Enable all strict standards conformance compiler options and disable
most Microsoft-specific compiler extensions (but not __declspec(dllimport) , for
example). This option is on by default in Visual Studio 2017 version 15.5. The
/permissive- conformance mode includes support for two-phase name lookup.

For more information, see C++ Conformance Improvements in Visual Studio.

/diagnostics: Enables display of the diagnostic error or warning location three


different ways: just the line number, the line number and column, or the line
number and column, with a caret under the offending line of code.

/debug:fastlink: Enable up to 30% faster incremental link times (vs. Visual Studio
2015) by not copying all debug information into the PDB file. The PDB file instead
points to the debug information for the object and library files used to create the
executable. See Faster C++ build cycle in VS "15" with /Debug:fastlink and
Recommendations to speed C++ builds in Visual Studio .

Visual Studio 2017 allows using /sdl with /await. We removed the /RTC limitation
with Coroutines.

Visual Studio 2017 version 15.3

/std:c++14 and /std:c++latest: These compiler options enable you to opt in to


specific versions of the ISO C++ programming language in a project. Most of the
new draft standard features are guarded by the /std:c++latest option.

/std:c++17 enables the set of C++17 features implemented by the compiler. This
option disables compiler and standard library support for features after C++17:
ones that are changed or new in later versions of the Working Draft, and defect
updates of the C++ Standard. To enable those features, use /std:c++latest .

Codegen, security, diagnostics, and versioning


This release brings several improvements in optimization, code generation, toolset
versioning, and diagnostics. Some notable improvements include:
Improved code generation of loops: Support for automatic vectorization of division
of constant integers, better identification of memset patterns.
Improved code security: Improved emission of buffer overrun compiler diagnostics,
and /guard:cf now guards switch statements that generate jump tables.
Versioning: The value of the built-in preprocessor macro _MSC_VER is now being
monotonically updated at every Visual C++ toolset update. For more information,
see Visual C++ Compiler Version .
New toolset layout: The compiler and related build tools have a new location and
directory structure on your development machine. The new layout enables side-
by-side installations of multiple versions of the compiler. For more information, see
Compiler Tools Layout in Visual Studio 2017 .
Improved diagnostics: The output window now shows the column where an error
occurs. For more information, see C++ compiler diagnostics improvements in VS
"15" Preview 5 .
When using coroutines, the experimental keyword yield (available under the
/await option) was removed. Your code should be updated to use co_yield

instead. For more information, see yield keyword to become co_yield in VS 2017 .

Visual Studio 2017 version 15.3

Improvements to diagnostics in the compiler. For more information, see Diagnostic


Improvements in Visual Studio 2017 15.3.0 .

Visual Studio 2017 version 15.5

Visual C++ runtime performance continues to improve through better generated code
quality. Now you can just recompile your code, and your app runs faster. Some of the
compiler optimizations are brand new, such as the vectorization of conditional scalar
stores, the combining of calls sin(x) and cos(x) into a new sincos(x) , and the
elimination of redundant instructions from the SSA optimizer. Other compiler
optimizations are improvements to existing functionality, such as: vectorizer heuristics
for conditional expressions, better loop optimizations, and float min/max codegen. The
linker has a new and faster /OPT:ICF implementation, which can result in up to 9% link-
time speedups, and there are other perf fixes in incremental linking. For more
information, see /OPT (Optimizations) and /INCREMENTAL (Link Incrementally).

The Microsoft C++ compiler supports Intel's AVX-512. It has Vector Length instructions
that bring new functions in AVX-512 to 128-bit and 256-bit wide registers.

The /Zc:noexceptTypes- option can be used to revert to the C++14 version of noexcept
while using C++17 mode in general. This option enables you to update your source
code to conform to C++17 without having to rewrite all your throw() code at the same
time. For more information, see Dynamic exception specification removal and noexcept.

Visual Studio 2017 version 15.7

New compiler switch /Qspectre to help mitigate against speculative execution


side-channel attacks. For more information, see Spectre mitigations in MSVC .
New diagnostic warning for Spectre mitigation. For more information, see Spectre
diagnostic in Visual Studio 2017 Version 15.7 Preview 4 .
A new value for /Zc, /Zc:__cplusplus , enables correct reporting of the C++
standard support. For example, when the switch is set and the compiler is in
/std:c++17 mode the value expands to 201703L . For more information, see MSVC
now correctly reports __cplusplus .

C++ standard library

Correctness Improvements

Visual Studio 2017 RTM (version 15.0)

Minor basic_string _ITERATOR_DEBUG_LEVEL != 0 diagnostics improvements. When


an IDL check gets tripped in string machinery, it now reports the specific behavior
that caused the trip. For example, instead of "string iterator not dereferencable"
you get "cannot dereference string iterator because it is out of range (e.g. an end
iterator)".
Fixed the std::promise move assignment operator, which previously could cause
code to block forever.
Fixed compiler errors with the atomic<T*> implicit conversion to T* .
pointer_traits<Ptr> now correctly detects Ptr::rebind<U> .

Fixed a missing const qualifier in the move_iterator subtraction operator.


Fixed silent bad codegen for stateful user-defined allocators requesting
propagate_on_container_copy_assignment and
propagate_on_container_move_assignment .

atomic<T> now tolerates overloaded operator&() .

Slightly improved compiler diagnostics for incorrect bind() calls.

There are more standard library improvements in Visual Studio 2017 RTM. For a
complete list, see the C++ Team Blog entry Standard Library Fixes In VS 2017 RTM .
Visual Studio 2017 version 15.3

Standard library containers now clamp their max_size() to


numeric_limits<difference_type>::max() rather than the max() of size_type . This

change ensures that the result of distance() on iterators from that container is
representable in the return type of distance() .
Fixed missing specialization auto_ptr<void> .
The for_each_n() , generate_n() , and search_n() algorithms previously failed to
compile if the length argument wasn't an integral type. They now attempt to
convert nonintegral lengths to the iterators' difference_type .
normal_distribution<float> no longer emits warnings inside the standard library
about narrowing from double to float.
Fixed some basic_string operations that used npos instead of max_size() when
checking for maximum size overflow.
condition_variable::wait_for(lock, relative_time, predicate) would wait for

the entire relative time if there was a spurious wake. Now it waits for only a single
interval of the relative time.
future::get() now invalidates the future , as the standard requires.
iterator_traits<void *> used to be a hard error because it attempted to form

void& ; it now cleanly becomes an empty struct to allow use of iterator_traits in

"is iterator" SFINAE conditions.


Some warnings reported by Clang -Wsystem-headers were fixed.
Also fixed "exception specification in declaration does not match previous
declaration" reported by Clang -Wmicrosoft-exception-spec .
Also fixed mem-initializer-list ordering warnings reported by Clang and C1XX.
The unordered containers didn't swap their hash functions or predicates when the
containers themselves were swapped. Now they do.
Many container swap operations are now marked noexcept (as our standard library
never intends to throw an exception when detecting the non-
propagate_on_container_swap non-equal-allocator undefined behavior condition).

Many vector<bool> operations are now marked noexcept .


The standard library now enforces matching allocator value_type (in C++17 mode)
with an opt-out escape hatch.
Fixed some conditions where self-range-insert into basic_string would scramble
the strings contents. (Note: self-range-insert into vectors is still prohibited by the
Standard.)
basic_string::shrink_to_fit() is no longer affected by the allocator's

propagate_on_container_swap .
std::decay now handles abominable function types, that is, function types that are

cv-qualified, ref-qualified, or both.


Changed include directives to use proper case sensitivity and forward slashes,
improving portability.
Fixed warning C4061 "enumerator 'enumerator' in switch of enum 'enumeration' is
not explicitly handled by a case label." This warning is off-by-default and was fixed
as an exception to the standard library's general policy for warnings. (The standard
library is /W4 clean, but doesn't attempt to be /Wall clean. Many off-by-default
warnings are unusually noisy, and aren't intended to be used on a regular basis.)
Improved std::list debug checks. List iterators now check operator->() , and
list::unique() now marks iterators as invalidated.

Fixed uses-allocator metaprogramming in tuple .

Visual Studio 2017 version 15.5

std::partition now calls the predicate N times instead of N + 1 times, as the

standard requires.
Attempts to avoid magic statics in version 15.3 are repaired in version 15.5.
std::atomic<T> no longer requires T to be default constructible.

Heap algorithms that take logarithmic time behave differently when iterator
debugging is enabled. They no longer do a linear time assertion that the input is in
fact a heap.
__declspec(allocator) is now guarded for C1XX only, to prevent warnings from

Clang, which doesn't understand this declspec.


basic_string::npos is now available as a compile time constant.

std::allocator in C++17 mode now properly handles allocation of over-aligned

types, that is, types whose alignment is greater than max_align_t , unless disabled
by /Zc:alignedNew- . For example, vectors of objects with 16-byte or 32-byte
alignment are now properly aligned for SSE and AVX instructions.

Conformance improvements
We added <any>, <string_view>, apply() , make_from_tuple() .
Added <optional>, <variant>, shared_ptr::weak_type , and <cstdalign>.
Enabled C++14 constexpr in min(initializer_list) , max(initializer_list) , and
minmax(initializer_list) , and min_element() , max_element() , and
minmax_element() .

For more information, see Microsoft C/C++ language conformance.


Visual Studio 2017 version 15.3

Several other C++17 features have been implemented. For more information, see
Microsoft C++ language conformance table.
Implemented P0602R0 "variant and optional should propagate copy/move
triviality".
The standard library now officially tolerates dynamic RTTI being disabled via the
/GR- option. Both dynamic_pointer_cast() and rethrow_if_nested() inherently
require dynamic_cast , so the standard library now marks them as =delete under
/GR- .

Even when dynamic RTTI is disabled via /GR- , "static RTTI" in the form of
typeid(SomeType) is still available, and powers several standard library

components. The standard library now supports disabling this feature too, via
/D_HAS_STATIC_RTTI=0 . This flag also disables std::any , the target() and

target_type() member functions of std::function , and the get_deleter() friend

member function of std::shared_ptr and std::weak_ptr .


The standard library now uses C++14 constexpr unconditionally, instead of
conditionally defined macros.
The standard library now uses alias templates internally.
The standard library now uses nullptr internally, instead of nullptr_t{} . (Internal
usage of NULL is eradicated. Internal usage of 0-as-null is being cleaned up
gradually.)
The standard library now uses std::move() internally, instead of stylistically
misusing std::forward() .
Changed static_assert(false, "message") to #error message . This change
improves compiler diagnostics because #error immediately stops compilation.
The standard library no longer marks functions as __declspec(dllimport) . Modern
linker technology no longer requires it.
Extracted SFINAE to default template arguments, which reduced clutter compared
to return types and function argument types.
Debug checks in <random> now use the standard library's usual machinery,
instead of the internal function _Rng_abort() , which called fputs() to stderr . This
function's implementation is kept for binary compatibility. We'll remove it in the
next binary-incompatible version of the standard library.

Visual Studio 2017 version 15.5

Several standard library features have been added, deprecated, or removed per the
C++17 standard. For more information, see C++ conformance improvements in
Visual Studio.
Experimental support for the following parallel algorithms:
all_of

any_of
for_each

for_each_n

none_of
reduce

replace
replace_if

sort

The signatures for the following parallel algorithms are added but not parallelized
at this time. Profiling showed no benefit in parallelizing algorithms that only move
or permute elements:
copy

copy_n

fill
fill_n

move
reverse

reverse_copy

rotate
rotate_copy

swap_ranges

Visual Studio 2017 version 15.6

<memory_resource>

Library Fundamentals V1
Deleting polymorphic_allocator assignment
Improving class template argument deduction

Visual Studio 2017 version 15.7

Support for parallel algorithms is no longer experimental


A new implementation of <filesystem>
Elementary string conversions (partial)
std::launder()
std::byte

hypot(x,y,z)
Avoiding unnecessary decay
Mathematical special functions
constexpr char_traits

Deduction guides for the standard library

For more information, see Microsoft C/C++ language conformance.

Performance and throughput fixes


Made basic_string::find(char) overloads only call traits::find once. Previously,
it was implemented as a general string search for a string of length 1.
basic_string::operator== now checks the string's size before comparing the

strings' contents.
Removed control coupling in basic_string , which was difficult for the compiler
optimizer to analyze. For all short strings, calling reserve still has a nonzero cost to
do nothing.
std::vector was overhauled for correctness and performance: aliasing during

insert and emplace operations is now correctly handled as required by the


Standard, the strong exception guarantee is now provided when required by the
Standard via move_if_noexcept() and other logic, and insert and emplace do fewer
element operations.
The C++ standard library now avoids dereferencing null fancy pointers.
Improved weak_ptr::lock() performance.
To increase compiler throughput, C++ standard library headers now avoid
including declarations for unnecessary compiler intrinsics.
Improved the performance of std::string and std::wstring move constructors
by more than three times.

Visual Studio 2017 version 15.3

Worked around interactions with noexcept , which prevented inlining the


std::atomic implementation into functions that use Structured Exception Handling

(SEH).
Changed the standard library's internal _Deallocate() function to optimize into
smaller code, allowing it to be inlined into more places.
Changed std::try_lock() to use pack expansion instead of recursion.
Improved the std::lock() deadlock avoidance algorithm to use lock()
operations instead of spinning on try_lock() on all the locks.
Enabled the Named Return Value Optimization in system_category::message() .
conjunction and disjunction now instantiate N + 1 types, instead of 2N + 2

types.
std::function no longer instantiates allocator support machinery for each type-

erased callable, improving throughput and reducing .obj size in programs that pass
many distinct lambdas to std::function .
allocator_traits<std::allocator> contains manually inlined std::allocator

operations, reducing code size in code that interacts with std::allocator through
allocator_traits only (that is, in most code).

The C++11 minimal allocator interface is now handled by the standard library
calling allocator_traits directly, instead of wrapping the allocator in an internal
class _Wrap_alloc . This change reduces the code size generated for allocator
support, improves the optimizer's ability to reason about standard library
containers in some cases, and provides a better debugging experience (as now you
see your allocator type, rather than _Wrap_alloc<your_allocator_type> in the
debugger).
Removed metaprogramming for customized allocator::reference , which
allocators aren't allowed to customize. (Allocators can make containers use fancy
pointers but not fancy references.)
The compiler front end was taught to unwrap debug iterators in range-based for
loops, improving the performance of debug builds.
The basic_string internal shrink path for shrink_to_fit() and reserve() is no
longer in the path of reallocating operations, reducing code size for all mutating
members.
The basic_string internal grow path is no longer in the path of shrink_to_fit() .
The basic_string mutating operations are now factored into non-allocating fast
path and allocating slow path functions, making it more likely for the common no-
reallocate case to be inlined into callers.
The basic_string mutating operations now construct reallocated buffers in the
preferred state rather than resizing in place. For example, an insert at the
beginning of a string now moves the content after the insertion exactly once. It's
moved either down or to the newly allocated buffer. It's no longer moved twice in
the reallocating case, first to the newly allocated buffer and then down.
Operations calling the C standard library in <string> now cache the errno address
to remove repeated interaction with TLS.
Simplified the is_pointer implementation.
Finished changing function-based Expression SFINAE to struct and void_t -based.
Standard library algorithms now avoid postincrementing iterators.
Fixed truncation warnings when using 32-bit allocators on 64-bit systems.
std::vector move assignment is now more efficient in the non-POCMA non-

equal-allocator case, by reusing the buffer when possible.

Visual Studio 2017 version 15.5

basic_string<char16_t> now engages the same memcmp , memcpy , and similar

optimizations that basic_string<wchar_t> engages.


An optimizer limitation that prevented function pointers from being inlined,
exposed by our "avoid copying functions" work in Visual Studio 2015 Update 3, has
been worked around, restoring performance of lower_bound(iter, iter, function
pointer) .

The overhead of iterator debugging's order verification of inputs to includes ,


set_difference , set_symmetric_difference , and set_union was reduced by

unwrapping iterators before checking order.


std::inplace_merge now skips over elements that are already in position.

Constructing std::random_device no longer constructs and then destroys a


std::string .

std::equal and std::partition had a jump-threading optimization pass that

saves an iterator comparison.


When std::reverse is passed pointers to trivially copyable T , it now dispatches to
a handwritten vectorized implementation.
std::fill , std::equal , and std::lexicographical_compare were taught how to

dispatch to memset and memcmp for std::byte and gsl::byte (and other char-like
enums and enum classes). Since std::copy dispatches using
is_trivially_copyable , it didn't need any changes.

The standard library no longer contains empty-braces destructors whose only


behavior was to make types non-trivially-destructible.

Other libraries

Open-source library support


Vcpkg is an open-source command-line tool that greatly simplifies the process of
acquiring and building open-source C++ static libs and DLLS in Visual Studio. For more
information, see vcpkg.

CPPRest SDK 2.9.0


Visual Studio 2017 version 15.5

The CPPRestSDK, a cross-platform web API for C++, is updated to version 2.9.0. For
more information, see CppRestSDK 2.9.0 is available on GitHub .

ATL

Visual Studio 2017 version 15.5

Yet another set of name-lookup conformance fixes


Existing move constructors and move assignment operators are now properly
marked as nonthrowing
Unsuppress valid warning C4640 about thread safe init of local statics in atlstr.h
Thread-safe initialization of local statics was automatically turned off in the XP
toolset when using ATL to build a DLL. Now it's not. You can add
/Zc:threadSafeInit- in your Project settings if you don't want thread-safe
initialization.

Visual C++ runtime


New header "cfguard.h" for Control Flow Guard symbols.

Visual Studio 2017 C++ IDE


Configuration change performance is now better for C++ native projects and
much better for C++/CLI projects. When a solution configuration is activated for
the first time, it is faster, and all later activations of this solution configuration is
almost instantaneous.

Visual Studio 2017 version 15.3

Several project and code wizards have been rewritten in the signature dialog style.
Add Class now launches the Add Class wizard directly. All of the other items that
were previously here are now available under Add > New Item.
Win32 projects are now under the Windows Desktop category in the New Project
dialog.
The Windows Console and Desktop Application templates now create the
projects without displaying a wizard. There's a new Windows Desktop Wizard
under the same category that displays the same options as the old Win32 Console
Application wizard.
Visual Studio 2017 version 15.5

Several C++ operations that use the IntelliSense engine for refactoring and code
navigation run much faster. The following numbers are based on the Visual Studio
Chromium solution with 3500 projects:

ノ Expand table

Feature Performance Improvement

Rename 5.3x

Change Signature 4.5x

Find All References 4.7x

C++ now supports Ctrl+Click Go To Definition, making mouse navigation to definitions


easy. The Structure Visualizer from the Productivity Power Tools pack is now also
included in the product by default.

IntelliSense
The new SQLite-based database engine is now being used by default. The new
engine speeds up database operations like Go To Definition and Find All
References. It significantly improves initial solution parse time. The setting moved
to Tools > Options > Text Editor > C/C++ > Advanced. (It was formerly under
...C/C++ > Experimental.)

We've improved IntelliSense performance on projects and files not using


precompiled headers - an Automatic Precompiled Header is created for headers in
the current file.

We've added error filtering and help for IntelliSense errors in the error list. Clicking
on the error column now allows for filtering. Also, clicking on the specific errors or
pressing F1 launches an online search for the error message.
Added the ability to filter Member List items by kind.

Added a new experimental Predictive IntelliSense feature that provides


contextually aware filtering of what appears in the Member List. For more
information, see C++ IntelliSense Improvements - Predictive IntelliSense &
Filtering .

Find All References (Shift+F12) now helps you get around easily, even in complex
codebases. It provides advanced grouping, filtering, sorting, searching within
results, and (for some languages) colorization, so you can get a clear
understanding of your references. For C++, the new UI includes information about
whether we're reading from or writing to a variable.

The Dot-to-Arrow IntelliSense feature moved from experimental to advanced, and


is now enabled by default. The editor features Expand Scopes and Expand
Precedence moved from experimental to advanced.

The experimental refactoring features Change Signature and Extract Function are
now available by default.

Added an experimental 'Faster project load' feature for C++ projects. The next
time you open a C++ project it will load faster, and the time after that it will load
much faster!
Some of these features are common to other languages, and some are specific to
C++. For more information about these new features, see Announcing Visual
Studio "15" Preview 5 .

Visual Studio 2017 version 15.7

Support added for ClangFormat. For more information, see ClangFormat Support
in Visual Studio 2017 .

Non-MSBuild projects with Open Folder


Visual Studio 2017 introduces the Open Folder feature. It enables you to code, build,
and debug in a folder containing source code without the need to create any solutions
or projects. Now it's simpler to get started with Visual Studio, even if your project isn't
an MSBuild-based project. Open Folder gives you access to powerful code
understanding, editing, building, and debugging capabilities. They're the same ones that
Visual Studio already provides for MSBuild projects. For more information, see Open
Folder projects for C++.

Improvements to the Open Folder experience. You can customize the experience
through these .json files:
CppProperties.json to customize the IntelliSense and browsing experience.
Tasks.json to customize the build steps.
Launch.json to customize the debugging experience.

Visual Studio 2017 version 15.3

Improved support for alternative compilers and build environments such as


MinGW and Cygwin. For more information, see Using MinGW and Cygwin with
Visual C++ and Open Folder .
Added support to define global and configuration-specific environment variables
in CppProperties.json and CMakeSettings.json. These environment variables can be
consumed by debug configurations defined in launch.vs.json and tasks in
tasks.vs.json. For more information, see Customizing your Environment with Visual
C++ and Open Folder .
Improved support for CMake's Ninja generator, including the ability to easily target
64-bit platforms.

CMake support via Open Folder


Visual Studio 2017 introduces support for using CMake projects without converting to
MSBuild project files (.vcxproj). For more information, see CMake projects in Visual
Studio. Opening CMake projects with Open Folder automatically configures the
environment for C++ editing, building, and debugging.

C++ IntelliSense works without the need to create a CppProperties.json file in the
root folder. We added a new dropdown to allow users to easily switch between
configurations provided by CMake and CppProperties.json files.

Further configuration is supported via a CMakeSettings.json file that sits in the


same folder as the CMakeLists.txt file.

Visual Studio 2017 version 15.3

Support added for the CMake Ninja generator.

Visual Studio 2017 version 15.4

Support added for importing existing CMake caches.

Visual Studio 2017 version 15.5

Support added for CMake 3.11, code analysis in CMake projects, Targets view in
Solution Explorer, options for cache generation, and single file compilation. For
more information, see CMake Support in Visual Studio and CMake projects in
Visual Studio.
Windows desktop development
We now provide a more granular installation experience for installing the original C++
workload. We added selectable components that enable you to install just the tools that
you need. The indicated installation sizes for the components listed in the installer UI are
incorrect, and underestimate the total size.

To successfully create Win32 projects in the C++ desktop workload, you must install
both a toolset and a Windows SDK. Install the recommended (selected) components
VC++ 2017 v141 toolset (x86, x64) and Windows 10 SDK (10.0.nnnnn) to make sure it
works. If the necessary tools aren't installed, projects won't be created successfully, and
the wizard stops responding.

Visual Studio 2017 version 15.5

The Visual C++ Build tools (previously available as a standalone product) are now
included as a workload in the Visual Studio Installer. This workload installs only the tools
required to build C++ projects without installing the Visual Studio IDE. Both the v140
and v141 toolsets are included. The v141 toolset contains the latest improvements in
Visual Studio 2017 version 15.5. For more information, see Visual Studio Build Tools now
include the VS2017 and VS2015 MSVC Toolsets .

Linux development with C++


The popular extension Visual C++ for Linux Development is now part of Visual Studio.
This installation provides everything you need to develop and debug C++ applications
running on a Linux environment.

Visual Studio 2017 version 15.2

Improvements were made in cross-platform code sharing and type visualization. For
more information, see Linux C++ improvements for cross-platform code sharing and
type visualization .

Visual Studio 2017 version 15.5

The Linux workload added support for rsync as an alternative to sftp for
synchronizing files to remote Linux machines.
Support is added for cross compilation targeting ARM microcontrollers. To enable
it in the installation, choose the Linux development with C++ workload and select
the option for Embedded and IoT Development. This option adds the ARM GCC
cross compilation tools and Make to your installation. For more information, see
ARM GCC Cross Compilation in Visual Studio .
Support added for CMake. You can now work on your existing CMake code base
without having to convert it to a Visual Studio project. For more information, see
Configure a Linux CMake Project.
Support added for running remote tasks. This capability allows you to run any
command on a remote system that is defined in Visual Studio's Connection
Manager. Remote tasks also provide the capability to copy files to the remote
system. For more information, see Configure a Linux CMake Project.

Visual Studio 2017 version 15.7

Various improvements to Linux workload scenarios. For more information, see


Linux C++ Workload improvements to the Project System, Linux Console Window,
rsync and Attach to Process .
IntelliSense for headers on remote Linux connections. For more information, see
IntelliSense for Remote Linux Headers and Configure a Linux CMake Project.

Game development with C++


Use the full power of C++ to build professional games powered by DirectX or Cocos2d.

Mobile development with C++ for Android and


iOS
You can now create and debug mobile apps using Visual Studio that can target Android
and iOS.

Universal Windows Apps


C++ comes as an optional component for the Universal Windows App workload.
Currently, you must upgrade C++ projects manually. You can open a v140-targeted
Universal Windows Platform project in Visual Studio 2017. However, you need to select
the v141 platform toolset in the project property pages if you don't have Visual Studio
2015 installed.

New options for C++ on Universal Windows


Platform (UWP)
You now have new options for writing and packaging C++ applications for the Universal
Windows Platform and the Windows Store: The Desktop Bridge infrastructure lets you
package your existing desktop application or COM object for deployment through the
Windows Store. Or, for deployment through your existing channels via side-loading.
New capabilities in Windows 10 enable you to add UWP functionality to your desktop
application in various ways. For more information, see Desktop Bridge.

Visual Studio 2017 version 15.5

A Windows Application Packaging Project project template is added, which greatly


simplifies packaging of desktop applications with Desktop Bridge. It's available under
File | New | Project | Installed | Visual C++ | Universal Windows Platform. For more
information, see Package an app by using Visual Studio (Desktop Bridge).

When writing new code, you can now use C++/WinRT, a standard C++ language
projection for the Windows Runtime implemented solely in header files. It allows you to
consume and author Windows Runtime APIs using any standards-conformant C++
compiler. C++/WinRT is designed to provide C++ developers with first-class access to
the modern Windows API. For more information, see C++/WinRT.

Starting in build 17025 of the Windows SDK Insider Preview, C++/WinRT is included in
the Windows SDK. For more information, see C++/WinRT is now included the Windows
SDK .

The Clang/C2 platform toolset


The Clang/C2 toolset that ships with Visual Studio 2017 now supports the /bigobj
switch, which is crucial for building large projects. It also includes several important bug
fixes, both in the compiler front-end and back-end.

C++ code analysis


The C++ Core Checkers for enforcing the C++ Core Guidelines are now distributed
with Visual Studio. Enable the checkers in the Code Analysis Extensions page in the
project's property pages. The extensions are then included when you run code analysis.
For more information, see Using the C++ Core Guidelines checkers.
Visual Studio 2017 version 15.3

Support added for rules related to resource management.

Visual Studio 2017 version 15.5

New C++ Core Guidelines checks cover smart pointer correctness, correct use of
global initializers, and flagging uses of constructs like goto and bad casts.

Some warning numbers you might find in 15.3 are no longer available in 15.5.
These warnings were replaced with more specific checks.

Visual Studio 2017 version 15.6

Support added for single-file analysis, and improvements in analysis run-time


performance. For more information, see C++ Static Analysis Improvements for
Visual Studio 2017 15.6 Preview 2

Visual Studio 2017 version 15.7

Support added for /analyze:ruleset, which lets you specify the code analysis rules
to run.
Support added for more C++ Core Guidelines rules. For more information, see
Using the C++ Core Guidelines checkers.

Unit testing in Visual Studio 2017

Visual Studio 2017 version 15.5

Google Test Adapter and Boost.Test Adapter are now available as components of the
Desktop Development with C++ workload. They're integrated with Test Explorer. CTest
support is added for CMake projects (using Open Folder), although full integration with
Test Explorer isn't available yet. For more information, see Writing unit tests for C/C++.

Visual Studio 2017 version 15.6

Support added for Boost.Test dynamic library support.


A Boost.Test item template is now available in the IDE.

For more information, see Boost.Test Unit Testing: Dynamic Library support and New
Item Template .

Visual Studio 2017 version 15.7

CodeLens support added for C++ unit test projects. For more information, see
Announcing CodeLens for C++ Unit Testing .

Visual Studio graphics diagnostics


Visual Studio Graphics Diagnostics tools: You can use them to record and analyze
rendering and performance problems in Direct3D apps. Use them on apps that run
locally on your Windows PC, in a Windows device emulator, or on a remote PC or
device.

Input & Output for Vertex and Geometry shaders: The ability to view input and
output of vertex shaders and geometry shaders has been one of the most
requested features. It's now supported in the tools. Select the VS or GS stage in the
Pipeline Stages view to start inspecting its input and output in the table below.
Search and filter in the object table: Provides a quick and easy way to find the
resources you're looking for.

Resource History: This new view provides a streamlined way of seeing the entire
modification history of a resource as it was used during the rendering of a
captured frame. To invoke the history for any resource, click the clock icon next to
any resource hyperlink.

It displays the new Resource History tool window, populated with the change
history of the resource.
You can capture frames with full call stack capturing enabled. That lets you quickly
deduce the context of each change event, and inspect it within your Visual Studio
project. Set the full stack capture option in the Visual Studio Tools > Options
dialog under Graphics Diagnostics.

API Statistics: View a high-level summary of API usage in your frame. It's handy for
discovering calls you might not realize you're making at all, or calls you're making
too often. This window is available via View > API Statistics in Visual Studio
Graphics Analyzer.
Memory Statistics: View how much memory the driver allocates for the resources
you create in the frame. This window is available via View > Memory Statistics in
Visual Studio Graphics Analyzer. To copy data to a CSV file for viewing in a
spreadsheet, right-click and choose Copy All.

Frame Validation: The new errors and warnings list provides an easy way to
navigate your event list based on potential issues detected by the Direct3D debug
layer. Click View > Frame Validation in Visual Studio Graphics Analyzer to open
the window. Then click Run Validation to start the analysis. It can take several
minutes to complete, depending on the frame's complexity.
Frame Analysis for D3D12: Use Frame Analysis to analyze draw-call performance
with directed "what-if" experiments. Switch to the Frame Analysis tab and run
analysis to view the report.

GPU Usage Improvements: Open traces can be taken via the Visual Studio GPU
Usage profiler with either GPUView or the Windows Performance Analyzer (WPA)
tool for more detailed analysis. If you have the Windows Performance Toolkit
installed, there are two hyperlinks: one for WPA and another for GPUView, at the
bottom right of the session overview.
Traces you open in GPUView via this link support synchronized VS and GPUView
timeline zooming and panning. A checkbox in VS controls whether synchronization
is enabled or not.
Microsoft C++ docs: What's new for
November 2023 to June 2024
Article • 06/27/2024

This article lists major changes to the Microsoft C++ docs for November 2023 to June
2024.

For what was new in the docs in previous months, see What's new history.
For what's new related to C++ in Visual Studio, see What's new for C++ in Visual
Studio.
For the latest C and C++ conformance with ISO standards status, see C++
conformance improvements in Visual Studio.

C/C++ compiler intrinsics and assembly language


Updated articles

ARM64 intrinsics - added entries to table for new arm64 intrinsics

Active Template Library (ATL), Microsoft Foundation


Classes (MFC)
Updated articles

Setting the Dialog Box's Background Color - add code example for setting a dialog
box's background color
Unicode and Multibyte Character Set (MBCS) Support - Clarified MBCS support in
unicode-and-multibyte-character-set-mbcs-support.md

C/C++ projects and build systems


New articles

/ARM64XFUNCTIONPADMINX64 (Minimum x64 function padding)


/NOFUNCTIONPADSECTION (Disable function padding)
/experimental:log (Structured SARIF diagnostics)
/feature (ARM64)
/LINKREPROFULLPATHRSP (Generate file containing absolute paths of linked files)
/Qspectre-jmp
/volatileMetadata (Generate metadata on volatile memory accesses)
Structured SARIF Diagnostics
Tutorial: Troubleshoot function inlining on build time
Tutorial: Troubleshoot header file impact on build time

Updated articles

/LARGEADDRESSAWARE (Handle Large Addresses) - largeaddressaware:no isn't


recommended for 64-bit apps
/Qspectre - New /QSpectre flag
/arch (ARM64) - document __arm_arch macro
Advanced Property Page - add SARIF diagnostics documentation
Linker options
new flag: /LINKREPROFULLPATHRSP
new linker switches for 17.8
Linking - new linker switches for 17.8

C language
New articles

typeof_unqual, __typeof_unqual__ (C23)


typeof, __typeof__ (C23)

Updated articles

C Keywords - conformance updates


C Type Specifiers - conformance updates

Code quality
New articles

Warning C26459
Warning C26837
Warning C26861
Warning C26862
Warning C26863
Warning C26864
Warning C6392
Warning C6393
Warning C6394
Warning C6396
Warning C6397
Warning C6398

Updated articles

Using Clang-Tidy in Visual Studio - fixed code example


Warning C6031 - fix some code examples
Warning C6059 - add heuristics
Warning C6201 - add heuristics

C++ in Visual Studio


Updated articles

break statement (C++) - doc fix


Examples of Lambda Expressions - fixed code example
Inline functions (C++) - address mistakes in inline functions cpp and remove
content contrasting inline functions and macros

Cross platform development


Updated articles

Install cross-platform mobile development with C++ - updates regarding Xamarin

C runtime library
Updated articles

Translation mode constants - clarify that _O_TEXT is ANSI

C/C++ compiler and tools errors and warnings


New articles

Compiler Error C2323


Compiler Warning (level 1) C5072
Compiler Warning (level 4) C5266
Compiler warning (level 4) C5267
Linker tools warning LNK4306
Linker tools warning LNK4307
Microsoft C/C++ compiler warnings C5000 through C5199
Microsoft C/C++ compiler warnings C5200 through C5399
Updated articles

Updated several compiler error and warning topics to include or refine examples.

C++ in Visual Studio tutorials


Updated articles

Create a console calculator in C++

Read and write code using C++ in Visual Studio


New articles

C++ Include Diagnostics in Visual Studio


Visualize C/C++ macro expansion

Updated articles

Walkthrough: Deploying Your Program (C++) - update steps

Linux with C++ in Visual Studio


Updated articles

Connect to your target Linux system in Visual Studio

C/C++ in Visual Studio overview


New articles

Microsoft Visual C++ compiler versioning

Updated articles

C++ Conformance improvements, behavior changes, and bug fixes in Visual Studio
2022 - updates for 17.10, added _alignof
Microsoft C++ docs: What's new for August 2023 to November 2023
What's new for C++ in Visual Studio 2022 - updates for 17.10

C++ porting and upgrade guide


Updated articles
C++ binary compatibility between Visual Studio versions - clarify linking binaries
built with different versions of the toolset

C/C++ preprocessor reference


Updated articles

Compiler warnings that are off by default - add new warning for VS 17.6 - C5266 &
C5267 and add warning level info
Predefined macros - documented __arm_arch macro

Overview of Windows programming in C++


Updated articles

ClickOnce Deployment for Visual C++ Applications - fixed code example


Microsoft Visual C++ Redistributable latest supported downloads - note 2013 no
longer supported and other updates

What's new history


This section lists major changes to the Microsoft C++ docs for August 2023 to early
November 2023.

Active Template Library (ATL), Microsoft Foundation


Classes (MFC)
Updated articles

CComDynamicUnkArray Class - updated remarks

C/C++ projects and build systems


New articles

/ifcMap
/Zc:checkGwOdr (Enforce Standard C++ ODR violations under /Gw)
/KERNEL (Create kernel mode binary)

Updated articles

Configure CMake debugging sessions - updated screenshots.


/permissive- (Standards conformance) - reflect new behavior as of 17.6
/Zc:externConstexpr (Enable extern constexpr variables) - reflect new behavior as
of 17.6
Overview of ARM64EC ABI conventions - ppdated register mapping for integer
registers table
/DEBUG (Generate debug info) - correct documentation for /DEBUG:FASTLINK and
/DEBUG

Code quality
New articles

Build reliable and secure C++ programs


Warning C6395
Warning C26479

Updated articles

How to specify additional code information by using _Analysis_assume_ - updated


remarks

Clarified behavior for the following warnings:

Warning C6053
Warning C26478
Warning C26817
Warning C26820

C++ in Visual Studio


New articles

alignas (C++)

Updated articles

alignas (C++) - updated remarks


if-else statement (C++) - improved code examples
__fastcall - added info about classes, structs, and unions
decltype (C++) - fixed code example
noreturn - improved example

C runtime library
Updated articles

fegetround, fesetround - noted change of values for FE_UPWARD and FE_DOWNWARD

C/C++ compiler and tools errors and warnings


Updated articles

Clarified behavior for the following warnings:

Compiler Error C2018, Compiler Error C2023


Compiler Error C2024, Compiler Error C2049
Compiler Error C2058, Compiler Error C2061
Compiler Error C2082, Compiler Error C2129
Compiler Error C2345, Compiler Error C2397
Compiler Error C2510, Compiler Error C2534
Compiler Error C2993, Compiler Error C3550
Compiler Error C3551

Read and write code using C++ in Visual Studio


New articles

Clean up C/C++ includes in Visual Studio


Configure C/C++ Include Cleanup in Visual Studio
Include Cleanup messages
lnt-make-member-function-const
lnt-naming-convention

C/C++ in Visual Studio overview


Updated articles

C++ Conformance improvements, behavior changes, and bug fixes in Visual Studio
2022 - added conformance updates for 17.7 and 17.8.
What's new for C++ in Visual Studio 2022 - updated what's new in C++.

C++ Standard Template Library (STL) reference


Updated articles

auto_ptr class - added deprecation info


Active Template Library (ATL), Microsoft Foundation
Classes (MFC)
Updated articles

Connection maps - corrected parameter description of pRefCount in


AfxConnection(Un)Advise

CSimpleStringT Class - updated code example


MFC class hierarchy chart - updated MFC hierarchy chart

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


C++ Conformance improvements,
behavior changes, and bug fixes in
Visual Studio 2022
Article • 08/08/2024

Microsoft C/C++ in Visual Studio (MSVC) makes conformance improvements and bug
fixes in every release. This article lists the significant improvements by major release,
then by version. To jump directly to the changes for a specific version, use the In this
article links.

This document lists the changes in Visual Studio 2022.

For changes in Visual Studio 2019, see C++ conformance improvements in Visual Studio
2019.
For changes in Visual Studio 2017, see C++ conformance improvements in Visual Studio
2017.
For changes in older versions, see Visual C++ What's New 2003 through 2015.

Conformance improvements in Visual Studio


2022 version 17.11
Visual Studio 2022 version 17.11 has the following conformance improvements, bug
fixes, and behavior changes in the Microsoft C/C++ compiler.

For an in-depth summary of changes made to the Standard Template Library, including
conformance changes, bug fixes, and performance improvements, see STL Changelog
VS 2022 17.11 .

Print blank lines with println


Per P3142R0 , it's now easy to generate a blank line with println . This feature is
available when compiling with /std:c++latest . Before this change, you wrote:
println(""); Now you write: println(); .

println(); is equivalent to println(stdout);


println(FILE* stream); is equivalent to println(stream, "\n");

Implemented range_formatter
Per P2286R8 , range_formatter is now implemented. This feature is available when
compiling with /std:c++latest .

Conformance improvements in Visual Studio


2022 version 17.10
Visual Studio 2022 version 17.10 has the following conformance improvements, bug
fixes, and behavior changes in the Microsoft C/C++ compiler.

For an in-depth summary of changes made to the Standard Template Library, including
conformance changes, bug fixes, and performance improvements, see STL Changelog
VS 2022 17.10 .

Conversion operator specialization with explicitly


specified return type
The compiler used to specialize conversion operators incorrectly in some cases, which
could lead to a mismatched return type. These invalid specializations no longer happen.
This is a source code breaking change.

C++

// Example 1
struct S
{
template<typename T> operator const T*();
};

void test()
{
S{}.operator int*(); // this is invalid now
S{}.operator const int*(); // this is valid
}

Added Support for #elifdef and #elifndef


Support added for WG21 P2334R1 (C++23) and WG14 N2645 (C++23) which
introduced the #elifdef and #elifndef preprocessor directives. Requires /std:clatest
or /std:c++latest .

Before:

C++
#ifdef __cplusplus
#include <atomic>
#elif !defined(__STDC_NO_ATOMICS__)
#include <stdatomic.h>
#else
#include <custom_atomics_library.h>
#endif

After:

C++

#ifdef __cplusplus
#include <atomic>
#elifndef __STDC_NO_ATOMICS__
#include <stdatomic.h>
#else
#include <custom_atomics_library.h>
#endif

Application of _Alignas on a structured type in C


Applies to the C language (C17 and later). Also added to Microsoft Visual Studio 17.9

In versions of Visual C++ before Visual Studio 2022 version 17.9, if the _Alignas
specifier appeared next to a structured type in a declaration, it wasn't applied correctly
according to the ISO-C Standard.

C++

// compile with /std:c17


#include <stddef.h>

struct Outer
{
_Alignas(32) struct Inner { int i; } member1;
struct Inner member2;
};
static_assert(offsetof(struct Outer, member2)==4, "incorrect alignment");

According to the ISO-C Standard, this code should compile without static_assert
emitting a diagnostic.

The _Alignas directive applies only to the member variable member1 . It must not change
the alignment of struct Inner . However, before Visual Studio 17.9.1, the diagnostic
"incorrect alignment" was emitted. The compiler aligned member2 to an offset of 32
bytes within the struct Outer type.

This is a binary breaking change, so a warning is now emitted when this change takes
effect. Warning C5274 is now emitted at warning level 1 for the previous example:
warning C5274: behavior change: _Alignas no longer applies to the type 'Inner'

(only applies to declared data objects) .

Also, in previous versions of Visual Studio, when the _Alignas specifier appeared next to
an anonymous type declaration, it was ignored.

C++

// compile with /std:c17


#include <stddef.h>
struct S
{
_Alignas(32) struct { int anon_member; };
int k;
};

static_assert(offsetof(struct S, k)==4, "incorrect offsetof");


static_assert(sizeof(struct S)==32, "incorrect size");

Previously, both static_assert statements failed when compiling this code. Now the
code compiles, but emits the following level 1 warnings:

warning C5274: behavior change: _Alignas no longer applies to the type


'<unnamed-tag>' (only applies to declared data objects)
warning C5273: behavior change: _Alignas on anonymous type no longer ignored
(promoted members will align)

To get the previous behavior, replace _Alignas(N) with __declspec(align(N)) . Unlike


_Alignas , declspec(align) applies to the type.

Improved warning C4706


This is a source code breaking change. Previously, the compiler didn't detect the
convention of wrapping an assignment in parentheses, if assignment was intended, to
suppress warning C4706 about assignment within a conditional expression. The
compiler now detects the parentheses and suppresses the warning.

C++
#pragma warning(error: 4706)

struct S
{
auto mf()
{
if (value = 9)
return value + 4;
else
return value;
}

int value = 9;
};

The compiler now also emits the warning in cases where the function isn't referenced.
Previously, because mf is an inline function that isn't referenced, warning C4706 wasn't
emitted for this code. Now the warning is emitted:

C++

error C4706: assignment used as a condition


note: if an assignment is intended you can enclose it in parentheses, '(e1 =
e2)', to silence this warning

To fix this warning, either use an equality operator, value == 9 , if this is what was
intended. Or, wrap the assignment in parentheses, (value = 9) , if assignment is
intended. Otherwise, since the function is unreferenced, remove it.

Conformance improvements in Visual Studio


2022 version 17.9
Visual Studio 2022 version 17.9 contains the following conformance improvements, bug
fixes, and behavior changes in the Microsoft C/C++ compiler.

For a broader summary of changes made to the Standard Template Library, see STL
Changelog VS 2022 17.9 .

Application of _Alignas on a structured type in C


In versions of Visual C++ before Visual Studio 2022 version 17.9, when _Alignas
appeared next to a structure type in a declaration, it wasn't applied correctly according
to the ISO-C Standard. For example:
C

// compile with /std:c17


#include <stddef.h>
struct Outer
{
_Alignas(32) struct Inner { int i; } member1;
struct Inner member2;
};
static_assert(offsetof(struct Outer, member2)==4, "incorrect alignment");

According to the ISO-C Standard, this code should compile without the static_assert
emitting a diagnostic. The _Alignas directive applies only to the member variable
member1 . It must not change the alignment of struct Inner . However, before release

17.9.1 of Visual Studio, the diagnostic "incorrect alignment" was emitted. The compiler
aligned member2 to a 32 byte offset within struct Outer .

Fixing this is a binary breaking change, so when this change in behavior is applied a
warning is emitted. For the preceding code, Warning C5274, " _Alignas no longer
applies to the type 'Inner' (only applies to declared data objects)" is now emitted at
warning level 1.

In previous versions of Visual Studio, _Alignas was ignored when it appeared next to an
anonymous type declaration. For example:

// compile with /std:c17


#include <stddef.h>
struct S {
_Alignas(32) struct { int anon_member; };
int k;
};
static_assert(offsetof(struct S, k)==4, "incorrect offsetof");
static_assert(sizeof(struct S)==32, "incorrect size");

Previously, both static_assert statements failed when compiling this code. The code
now compiles, but with the following level 1 warnings:

warning C5274: behavior change: _Alignas no longer applies to the type


'<unnamed-tag>' (only applies to declared data objects)
warning C5273: behavior change: _Alignas on anonymous type no longer ignored
(promoted members will align)
If you want the earlier behavior, replace _Alignas(N) with __declspec(align(N)) . Unlike
_Alignas , declspec(align) can be applied to a type.

__VA_OPT__ is enabled as an extension under


/Zc:preprocessor

__VA_OPT__ was added to C++20 and C23. Previous to its addition, there wasn't a

standard way to elide a comma in a variadic macro. To provide better backward


compatibility, __VA_OPT__ is enabled under the token based preprocessor
/Zc:preprocessor across all language versions.

For example, this now compiles without error:

C++

#define LOG_WRAPPER(message, ...) WRITE_LOG(__LINE__, message __VA_OPT__(,


__VA_ARGS__))

// Failed to build under /std:c11, now succeeds.


LOG_WRAPPER("Log message");
LOG_WRAPPER("Log message with %s", "argument")

C23 language
For C23, the following are available when using the /std:clatest compiler switch:

typeof
typeof_unqual

The following are available for all C language versions:

__typeof__
__typeof_unqual__

C++ Standard Library


C++23 features

formattable , range_format , format_kind , and set_debug_format() as part of

P2286R8 Formatting Ranges


<mdspan> per P0009R18 and subsequent wording changes that were applied to
the C++23 Standard.
format() pointers per P2510R3 .
Conformance improvements in Visual Studio
2022 version 17.8
Visual Studio 2022 version 17.8 contains the following conformance improvements, bug
fixes, and behavior changes in the Microsoft C/C++ compiler.

/FU issues an error

The C compiler used to accept the /FU option, even though it hasn't support managed
compilation for some time. It now issues an error. Projects that pass this option need to
restrict it to C++/CLI projects only.

C++ Standard Library


The C++23 named modules std and std.compat are now available when compiling with
/std:c++20 .

For a broader summary of changes made to the C++ Standard Library, see STL
Changelog VS 2022 17.8 .

Conformance improvements in Visual Studio


2022 version 17.7
Visual Studio 2022 version 17.7 contains the following highlighted conformance
improvements, bug fixes, and behavior changes in the Microsoft C/C++ compiler.

Added /std:clatest to the C compiler


This switch behaves like the /std:c++latest switch for the C++ compiler. The switch
enables all currently implemented compiler and standard library features proposed for
the next draft C standard, as well as some in-progress and experimental features.

C++ Standard Library


The <print> library is now supported. See P2093R14 Formatted output .

Implemented views::cartesian_product .
For a broader summary of changes made to the Standard Template Library, see STL
Changelog VS 2022 17.7 .

using conformance

Previously, the using directive could cause names from used namespaces to remain
visible when they shouldn't. This could cause unqualified name lookup to find a name in
a namespace even when there's no using directive active.

Here are some examples of the new and old behavior.


References in the following comments to "(1)" mean the call to f<K>(t) in namespace
A:

C++

namespace A
{
template<typename K, typename T>
auto f2(T t)
{
return f<K>(t); // (1) Unqualified lookup should not find anything
}
}

namespace B
{
template<typename K, typename T>
auto f(T t) noexcept
{ // Previous behavior: This function was erroneously found during
unqualified lookup at (1)
return A::f2<K>(t);
}
}

namespace C
{
template<typename T>
struct S {};

template<typename, typename U>


U&& f(U&&) noexcept; // New behavior: ADL at (1) correctly finds this
function
}

namespace D
{
using namespace B;

void h()
{
D::f<void>(C::S<int>());
}
}

The same underlying issue can cause code that previously compiled to now be rejected:

C++

#include <memory>
namespace Addin {}
namespace Gui
{
using namespace Addin;
}

namespace Addin
{
using namespace std;
}

// This previously compiled, but now emits error C2065 for undeclared name
'allocator'.
// This should be declared as 'std::allocator<T*>' because the using
directive nominating
// 'std' is not active at this point.
template <class T, class U = allocator<T*>>
class resource_list
{
};

namespace Gui
{
typedef resource_list<int> intlist;
}

Conformance improvements in Visual Studio


2022 version 17.6
Visual Studio 2022 version 17.6 contains the following conformance improvements, bug
fixes, and behavior changes in the Microsoft C/C++ compiler.

Compound volatile assignments no longer deprecated


C++20 deprecated applying certain operators to types qualified with volatile . For
example, when the following code is compiled with cl /std:c++20 /Wall test.cpp :

C++
void f(volatile int& expr)
{
++expr;
}

The compiler produces test.cpp(3): warning C5214: applying '++' to an operand with
a volatile qualified type is deprecated in C++20 .

In C++20, compound assignment operators (operators of the form @= ) were


deprecated. In C++23, compound operators excluded in C++20 are no longer
deprecated. For example, in C++23 the following code doesn't produce a warning,
whereas it does in C++20:

C++

void f(volatile int& e1, int e2)


{
e1 += e2;
}

For more information about this change, see CWG:2654

Rewriting equality in expressions is less of a breaking


change (P2468R2)
In C++20, P2468R2 changed the compiler to accept code such as:

C++

struct S
{
bool operator==(const S&);
bool operator!=(const S&);
};
bool b = S{} != S{};

The compiler accepts this code, which means that the compiler is more strict with code
such as:

c++

struct S
{
operator bool() const;
bool operator==(const S&);
};

bool b = S{} == S{};

Version 17.5 of the compiler accepts this program. Version 17.6 of the compiler rejects it.
To fix it, add const to operator== to remove the ambiguity. Or, add a corresponding
operator!= to the definition as shown in the following example:

C++

struct S
{
operator bool() const;
bool operator==(const S&);
bool operator!=(const S&);
};

bool b = S{} == S{};

Microsoft C/C++ compiler versions 17.5 and 17.6 accept the previous program, and calls
S::operator== in both versions.

The general programming model outlined in P2468R2 is that if there's a corresponding


operator!= for a type, it typically suppresses the rewrite behavior. Adding a

corresponding operator!= is the suggested fix for code that previously compiled in
C++17. For more information, see Programming Model .

Conformance improvements in Visual Studio


2022 version 17.4
Visual Studio 2022 version 17.4 contains the following conformance improvements, bug
fixes, and behavior changes in the Microsoft C/C++ compiler.

Underlying types of unscoped enum with no fixed type


In versions of Visual Studio before Visual Studio 2022 version 17.4, the C++ compiler
didn't correctly determine the underlying type of an unscoped enumeration with no
fixed base type. Under /Zc:enumTypes, we now correctly implement the standard
behavior.

The C++ Standard requires the underlying type of an enum to be large enough to hold
all enumerators in that enum . Sufficiently large enumerators can set the underlying type
of the enum to unsigned int , long long , or unsigned long long . Previously, such enum
types always had an underlying type of int in the Microsoft compiler, regardless of
enumerator values.

When enabled, the /Zc:enumTypes option is a potential source and binary breaking
change. It's off by default, and not enabled by /permissive- , because the fix might
affect binary compatibility. Some enumeration types change size when the conformant
fix is enabled. Certain Windows SDK headers include such enumeration definitions.

Example

C++

enum Unsigned
{
A = 0xFFFFFFFF // Value 'A' does not fit in 'int'.
};

// Previously, failed this static_assert. Now passes with /Zc:enumTypes.


static_assert(std::is_same_v<std::underlying_type_t<Unsigned>, unsigned
int>);

template <typename T>


void f(T x)
{
}

int main()
{
// Previously called f<int>, now calls f<unsigned int>.
f(+A);
}

// Previously this enum would have an underlying type of `int`, but Standard
C++ requires this to have
// a 64-bit underlying type. Using /Zc:enumTypes changes the size of this
enum from 4 to 8, which could
// impact binary compatibility with code compiled with an earlier compiler
version or without the switch.
enum Changed
{
X = -1,
Y = 0xFFFFFFFF
};

Types of enumerators within an enum definition with no


fixed underlying type
In versions of Visual Studio before Visual Studio 2022 version 17.4, the C++ compiler
didn't correctly model the types of enumerators. It could assume an incorrect type in
enumerations without a fixed underlying type before the closing brace of the
enumeration. Under /Zc:enumTypes, the compiler now correctly implements the
standard behavior.

The C++ Standard specifies that within an enumeration definition of no fixed underlying
type, initializers determine the types of enumerators. Or, for the enumerators with no
initializer, by the type of the previous enumerator (accounting for overflow). Previously,
such enumerators were always given the deduced type of the enumeration, with a
placeholder for the underlying type (typically int ).

When enabled, the /Zc:enumTypes option is a potential source and binary breaking
change. It's off by default, and not enabled by /permissive- , because the fix might
affect binary compatibility. Some enumeration types change size when the conformant
fix is enabled. Certain Windows SDK headers include such enumeration definitions.

Example

C++

enum Enum {
A = 'A',
B = sizeof(A)
};

static_assert(B == 1); // previously failed, now succeeds under


/Zc:enumTypes

In this example the enumerator A should have type char before the closing brace of the
enumeration, so B should be initialized using sizeof(char) . Before the /Zc:enumTypes
fix, A had enumeration type Enum with a deduced underlying type int , and B was
initialized using sizeof(Enum) , or 4.

Conformance improvements in Visual Studio


2022 version 17.3
Visual Studio 2022 version 17.3 contains the following conformance improvements, bug
fixes, and behavior changes in the Microsoft C/C++ compiler.
C: Improved modifier compatibility checking between
pointers
The C compiler didn't properly compare modifiers between pointers, especially void* .
This defect could result in an improper diagnosis of incompatibility between const
int** and void* and compatibility between int* volatile* and void* .

Example

void fn(void* pv) { (pv); }

int main()
{
int t = 42;
int* pt = &t;
int* volatile * i = &pt;
fn(i); // Now raises C4090
const int** j = &pt;
fn(j); // No longer raises C4090
}

Conformance improvements in Visual Studio


2022 version 17.2
Visual Studio 2022 version 17.2 contains the following conformance improvements, bug
fixes, and behavior changes in the Microsoft C/C++ compiler.

Unterminated bidirectional character warnings


Visual Studio 2022 version 17.2 adds level 3 warning C5255 for unterminated Unicode
bidirectional characters in comments and strings. The warning addresses a security
concern described in Trojan Source: Invisible Vulnerabilities by Nicholas Boucher and
Ross Anderson. For more information on Unicode bidirectional characters, see
Unicode® Standard Annex #9: UNICODE BIDIRECTIONAL ALGORITHM .

Warning C5255 only addresses files that, after conversion, contain Unicode bidirectional
characters. This warning applies to UTF-8, UTF-16, and UTF-32 files, so the proper
source-encoding must be provided. This change is a source breaking change.
Example (before/after)
In versions of Visual Studio before Visual Studio 2022 version 17.2, an unterminated
bidirectional character didn't produce a warning. Visual Studio 2022 version 17.2
produces warning C5255:

C++

// bidi.cpp
int main() {
const char *access_level = "user";
// The following source line contains bidirectional Unicode characters
equivalent to:
// if ( strcmp(access_level, "user\u202e \u2066// Check if admin
\u2069 \u2066") ) {
// In most editors, it's rendered as:
// if ( strcmp(access_level, "user") ) { // Check if admin
if ( strcmp(access_level, "user") ) {⁦⁩
// Check if admin ⁦‫‮‬
printf("You are an admin.\n");
}
return 0;
}

/* build output
bidi.cpp(8): warning C5255: unterminated bidirectional character
encountered: 'U+202e'
bidi.cpp(8): warning C5255: unterminated bidirectional character
encountered: 'U+2066'
*/

from_chars() float tiebreaker

Visual Studio 2022 version 17.2 fixes a bug in <charconv> from_chars() float tiebreaker
rules that produced incorrect results. This bug affected decimal strings that were at the
exact midpoint of consecutive float values, within a narrow range. (The smallest and
largest affected values were 32768.009765625 and 131071.98828125 , respectively.) The
tiebreaker rule wanted to round to "even", and "even" happened to be "down", but the
implementation incorrectly rounded "up" ( double was unaffected.) For more information
and implementation details, see microsoft/STL#2366 .

This change affects runtime behavior in the specified range of cases:

Example

C++
// from_chars_float.cpp
#include <cassert>
#include <charconv>
#include <cstdio>
#include <string_view>
#include <system_error>
using namespace std;
int main() {
const double dbl = 32768.009765625;
const auto sv = "32768.009765625"sv;
float flt = 0.0f;
const auto result = from_chars(sv.data(), sv.data() + sv.size(), flt);
assert(result.ec == errc{});
printf("from_chars() returned: %.1000g\n", flt);
printf("This rounded %s.\n", flt < dbl ? "DOWN" : "UP");
}

In versions before Visual Studio 2022 version 17.2:

Output

C:\Temp>cl /EHsc /nologo /W4 /std:c++17 from_chars_float.cpp &&


from_chars_float
from_chars_float.cpp
from_chars() returned: 32768.01171875
This rounded UP.

In Visual Studio 2022 version 17.2 and after:

Output

C:\Temp>cl /EHsc /nologo /W4 /std:c++17 from_chars_float.cpp &&


from_chars_float
from_chars_float.cpp
from_chars() returned: 32768.0078125
This rounded DOWN.

/Zc:__STDC__ makes __STDC__ available for C

The C standard requires that a conforming C implementation defines __STDC__ as 1 .


Due to the behavior of the UCRT, which doesn't expose POSIX functions when __STDC__
is 1 , it isn't possible to define this macro for C by default without introducing breaking
changes to the stable language versions. Visual Studio 2022 version 17.2 and later add a
conformance option /Zc:__STDC__ that defines this macro. There's no negative version of
the option. Currently, we plan to use this option by default for future versions of C.
This change is a source breaking change. It applies when C11 or C17 mode is enabled
( /std:c11 or /std:c17 ) and /Zc:__STDC__ is specified.

Example

// test__STDC__.c
#include <io.h>
#include <fcntl.h>
#include <stdio.h>

int main() {
#if __STDC__
int f = _open("file.txt", _O_RDONLY);
_close(f);
#else
int f = open("file.txt", O_RDONLY);
close(f);
#endif
}

/* Command line behavior

C:\Temp>cl /EHsc /W4 /Zc:__STDC__ test__STDC__.c && test__STDC__

*/

Warning for missing braces


Warning C5246 reports missing braces during aggregate initialization of a subobject.
Before Visual Studio 2022 version 17.2, the warning didn't handle the case of an
anonymous struct or union .

This change is a source breaking change. It applies when the off-by-default warning
C5246 is enabled.

Example

In Visual Studio 2022 version 17.2 and later, this code now causes an error:

C++

struct S {
union {
float f[4];
double d[2];
};
};

void f()
{
S s = { 1.0f, 2.0f, 3.14f, 4.0f };
}

/* Command line behavior


cl /Wall /c t.cpp

t.cpp(10): warning C5246: 'anonymous struct or union': the initialization of


a subobject should be wrapped in braces
*/

To resolve this issue, add braces to the initializer:

C++

void f()
{
S s = { { 1.0f, 2.0f, 3.14f, 4.0f } };
}

Conformance improvements in Visual Studio


2022 version 17.1
Visual Studio 2022 version 17.1 contains the following conformance improvements, bug
fixes, and behavior changes in the Microsoft C/C++ compiler.

Detect ill-formed capture default in nonlocal lambda-


expressions
The C++ Standard only allows a lambda expression in block scope to have a capture-
default. In Visual Studio 2022 version 17.1 and later, the compiler detects when a
capture default isn't allowed in a nonlocal lambda expression. It emits a new level 4
warning, C5253.

This change is a source breaking change. It applies in any mode that uses the new
lambda processor: /Zc:lambda , /std:c++20 , or /std:c++latest .

Example
In Visual Studio 2022 version 17.1 this code now emits an error:
C++

#pragma warning(error:5253)

auto incr = [=](int value) { return value + 1; };

// capture_default.cpp(3,14): error C5253: a nonlocal lambda cannot have a


capture default
// auto incr = [=](int value) { return value + 1; };
// ^

To fix this issue, remove the capture default:

C++

#pragma warning(error:5253)

auto incr = [](int value) { return value + 1; };

C4028 is now C4133 for function-to-pointer operations


Before Visual Studio 2022 version 17.1, the compiler reported an incorrect error
message on certain pointer-to-function comparisons in C code. The incorrect message
was reported when you compared two function pointers that had the same argument
counts but incompatible types. Now, we issue a different warning that complains about
pointer-to-function incompatibility rather than function parameter mismatch.

This change is a source breaking change. It applies when code is compiled as C.

Example

int f1(int);
int f2(char*);
int main(void)
{
return (f1 == f2);
}
// Old warning:
// C4028: formal parameter 1 different from declaration
// New warning:
// C4113: 'int (__cdecl *)(char *)' differs in parameter lists from 'int
(__cdecl *)(int)'
Error on a nondependent static_assert
In Visual Studio 2022 version 17.1 and later, if the expression associated with a
static_assert isn't a dependent expression, the compiler evaluates the expression

when it's parsed. If the expression evaluates to false , the compiler emits an error.
Previously, if the static_assert was within the body of a function template (or within
the body of a member function of a class template), the compiler wouldn't perform this
analysis.

This change is a source breaking change. It applies in any mode that implies
/permissive- or /Zc:static_assert . This change in behavior can be disabled by using

the /Zc:static_assert- compiler option.

Example
In Visual Studio 2022 version 17.1 and later, this code now causes an error:

C++

template<typename T>
void f()
{
static_assert(false, "BOOM!");
}

To fix this issue, make the expression dependent. For example:

C++

template<typename>
constexpr bool dependent_false = false;

template<typename T>
void f()
{
static_assert(dependent_false<T>, "BOOM!");
}

With this change, the compiler only emits an error if the function template f is
instantiated.

Conformance improvements in Visual Studio


2022 version 17.0
Visual Studio 2022 version 17.0 contains the following conformance improvements, bug
fixes, and behavior changes in the Microsoft C/C++ compiler.

Warning on bitfield width for enumeration type


When you declare an instance of an enumeration type as a bitfield, the width of the
bitfield must accommodate all possible values of the enumeration. Otherwise, the
compiler issues a diagnostic message. Consider this example: Consider:

C++

enum class E : unsigned { Zero, One, Two };

struct S {
E e : 1;
};

A programmer might expect the class member S::e can hold any of the explicitly
named enum values. Given the number of enumeration elements, it isn't possible. The
bitfield can't cover the range of explicitly provided values of E (conceptually, the
domain of E ). To address the concern that the bitfield width isn't large enough for the
domain of the enumeration, a new (off by default) warning is added to MSVC:

Output

t.cpp(4,5): warning C5249: 'S::e' of type 'E' has named enumerators with
values that cannot be represented in the given bit field width of '1'.
E e : 1;
^
t.cpp(1,38): note: see enumerator 'E::Two' with value '2'
enum class E : unsigned { Zero, One, Two };
^

This compiler behavior is a source and binary breaking change that affects all /std and
/permissive modes.

Error on ordered pointer comparison against nullptr or 0


The C++ Standard inadvertently allowed an ordered pointer comparison against
nullptr or 0. For example:

C++
bool f(int *p)
{
return p >= 0;
}

WG21 paper N3478 removed this oversight. This change is implemented in MSVC.
When the example is compiled by using /permissive- (and /diagnostics:caret ), it
emits the following error:

Output

t.cpp(3,14): error C7664: '>=': ordered comparison of pointer and integer


zero ('int *' and 'int')
return p >= 0;
^

This compiler behavior is a source and binary breaking change that affects code
compiled using /permissive- in all /std modes.

See also
Microsoft C/C++ language conformance

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


C++ Conformance improvements,
behavior changes, and bug fixes in
Visual Studio 2019
Article • 12/21/2022

Microsoft C/C++ in Visual Studio (MSVC) makes conformance improvements and bug
fixes in every release. This article lists the improvements by major release, then by
version. To jump directly to the changes for a specific version, use the list below In this
article.

This document lists the changes in Visual Studio 2019. For a guide to the changes in
Visual Studio 2022, see C++ conformance improvements in Visual Studio 2022. For
changes in Visual Studio 2017, see C++ conformance improvements in Visual Studio
2017. For a complete list of previous conformance improvements, see Visual C++
What's New 2003 through 2015.

Conformance improvements in Visual Studio


2019 RTW (version 16.0)
Visual Studio 2019 RTW contains the following conformance improvements, bug fixes,
and behavior changes in the Microsoft C++ compiler.

7 Note

C++20 features were available only in /std:c++latest mode in Visual Studio 2019
until the C++20 implementation was considered complete. Visual Studio 2019
version 16.11 introduces the /std:c++20 compiler mode. In this article, features that
originally required /std:c++latest mode now work in /std:c++20 mode or later in
the latest versions of Visual Studio. We've updated the documentation to mention
/std:c++20 , even though this option wasn't available when the features were first

released.

Improved modules support for templates and error


detection
Modules are now officially in the C++20 standard. Improved support was added in
Visual Studio 2017 version 15.9. For more information, see Better template support and
error detection in C++ Modules with MSVC 2017 version 15.9 .

Modified specification of aggregate type


The specification of an aggregate type has changed in C++20 (see Prohibit aggregates
with user-declared constructors ). In Visual Studio 2019, under /std:c++latest (or
/std:c++20 in Visual Studio 2019 version 16.11 and later), a class with any user-declared

constructor (for example, including a constructor declared = default or = delete ) isn't


an aggregate. Previously, only user-provided constructors would disqualify a class from
being an aggregate. This change puts more restrictions on how such types can be
initialized.

The following code compiles without errors in Visual Studio 2017 but raises errors C2280
and C2440 in Visual Studio 2019 under /std:c++20 or /std:c++latest :

C++

struct A
{
A() = delete; // user-declared ctor
};

struct B
{
B() = default; // user-declared ctor
int i = 0;
};

A a{}; // ill-formed in C++20, previously well-formed


B b = { 1 }; // ill-formed in C++20, previously well-formed

Partial support for operator <=>


P0515R3 C++20 introduces the <=> three-way comparison operator, also known as
the "spaceship operator". Visual Studio 2019 version 16.0 in /std:c++latest mode
introduces partial support for the operator by raising errors for syntax that's now
disallowed. For example, the following code compiles without errors in Visual Studio
2017 but raises multiple errors in Visual Studio 2019 under /std:c++20 or
/std:c++latest :

C++

struct S
{
bool operator<=(const S&) const { return true; }
};

template <bool (S::*)(const S&) const>


struct U { };

int main(int argc, char** argv)


{
U<&S::operator<=> u; // In Visual Studio 2019 raises C2039, 2065, 2146.
}

To avoid the errors, insert a space in the offending line before the final angle bracket:
U<&S::operator<= > u; .

References to types with mismatched cv-qualifiers

7 Note

This change only affects Visual Studio 2019 versions 16.0 through 16.8. It was
reverted starting in Visual Studio 2019 version 16.9

Previously, MSVC allowed direct binding of a reference from a type with mismatched cv-
qualifiers below the top level. This binding could allow modification of supposedly const
data referred to by the reference.

The compiler for Visual Studio 2019 versions 16.0 through 16.8 instead creates a
temporary, as was required by the standard at that time. Later, the standard retroactively
changed making the previous behavior of Visual Studio 2017 and earlier correct, and the
behavior of Visual Studio 2019 version 16.0 through 16.8 wrong. Consequently, this
change was reverted starting in Visual Studio 2019 version 16.9.

See Similar types and reference binding for a related change.

As an example, in Visual Studio 2017, the following code compiles without warnings. In
Visual Studio 2019 versions 16.0 through 16.8, the compiler raises warning C4172.
Starting with Visual Studio 2019 version 16.9, the code once again compiles without
warnings:

C++

struct X
{
const void* const& PData() const
{
return _pv;
}

void* _pv;
};

int main()
{
X x;
auto p = x.PData(); // C4172 <func:#1 "?PData@X@@QBEABQBXXZ"> returning
address of local variable or temporary
}

reinterpret_cast from an overloaded function

The argument to reinterpret_cast isn't one of the contexts in which the address of an
overloaded function is permitted. The following code compiles without errors in Visual
Studio 2017, but in Visual Studio 2019 it raises error C2440:

C++

int f(int) { return 1; }


int f(float) { return .1f; }
using fp = int(*)(int);

int main()
{
fp r = reinterpret_cast<fp>(&f); // C2440: cannot convert from
'overloaded-function' to 'fp'
}

To avoid the error, use an allowed cast for this scenario:

C++

int f(int);
int f(float);
using fp = int(*)(int);

int main()
{
fp r = static_cast<fp>(&f); // or just &f;
}

Lambda closures
In C++14, lambda closure types aren't literals. The primary consequence of this rule is
that a lambda may not be assigned to a constexpr variable. The following code
compiles without errors in Visual Studio 2017, but in Visual Studio 2019 it raises error
C2127:

C++

int main()
{
constexpr auto l = [] {}; // C2127 'l': illegal initialization of
'constexpr' entity with a non-constant expression
}

To avoid the error, either remove the constexpr qualifier, or else change the
conformance mode to /std:c++17 or later.

std::create_directory failure codes

Implemented P1164 from C++20 unconditionally. This changes


std::create_directory to check whether the target was already a directory on failure.

Previously, all ERROR_ALREADY_EXISTS type errors were turned into success-but-


directory-not-created codes.

operator<<(std::ostream, nullptr_t)

Per LWG 2221 , added operator<<(std::ostream, nullptr_t) for writing nullptr to


streams.

More parallel algorithms


New parallel versions of is_sorted , is_sorted_until , is_partitioned , set_difference ,
set_intersection , is_heap , and is_heap_until .

Fixes in atomic initialization


P0883 "Fixing atomic initialization" changes std::atomic to value-initialize the
contained T rather than default-initializing it. The fix is enabled when using Clang/LLVM
with the Microsoft standard library. It's currently disabled for the Microsoft C++
compiler, as a workaround for a bug in constexpr processing.

remove_cvref and remove_cvref_t


Implemented the remove_cvref and remove_cvref_t type traits from P0550 . These
remove reference-ness and cv-qualification from a type without decaying functions and
arrays to pointers (unlike std::decay and std::decay_t ).

Feature-test macros
P0941R2 - feature-test macros is complete, with support for __has_cpp_attribute .
Feature-test macros are supported in all standard modes.

Prohibit aggregates with user-declared constructors


C++20 P1008R1 - prohibiting aggregates with user-declared constructors is complete.

reinterpret_cast in a constexpr function

A reinterpret_cast is illegal in a constexpr function. The Microsoft C++ compiler


would previously reject reinterpret_cast only if it were used in a constexpr context. In
Visual Studio 2019, in all language standards modes, the compiler correctly diagnoses a
reinterpret_cast in the definition of a constexpr function. The following code now

produces C3615:

C++

long long i = 0;
constexpr void f() {
int* a = reinterpret_cast<int*>(i); // C3615: constexpr function 'f'
cannot result in a constant expression
}

To avoid the error, remove the constexpr modifier from the function declaration.

Correct diagnostics for basic_string range constructor


In Visual Studio 2019, the basic_string range constructor no longer suppresses
compiler diagnostics with static_cast . The following code compiles without warnings
in Visual Studio 2017, despite the possible loss of data from wchar_t to char when
initializing out :

C++

std::wstring ws = /* . . . */;
std::string out(ws.begin(), ws.end()); // VS2019 C4244: 'argument':
conversion from 'wchar_t' to 'const _Elem', possible loss of data.

Visual Studio 2019 correctly raises warning C4244. To avoid the warning, you can
initialize the std::string as shown in this example:

C++

std::wstring ws = L"Hello world";


std::string out;
for (wchar_t ch : ws)
{
out.push_back(static_cast<char>(ch));
}

Incorrect calls to += and -= under /clr or /ZW are now


correctly detected
A bug was introduced in Visual Studio 2017 that caused the compiler to silently ignore
errors and generate no code for the invalid calls to += and -= under /clr or /ZW . The
following code compiles without errors in Visual Studio 2017 but in Visual Studio 2019 it
correctly raises error C2845:

C++

public enum class E { e };

void f(System::String ^s)


{
s += E::e; // in VS2019 C2845: 'System::String ^': pointer arithmetic
not allowed on this type.
}

To avoid the error in this example, use the += operator with the ToString() method: s
+= E::e.ToString(); .

Initializers for inline static data members


Invalid member accesses within inline and static constexpr initializers are now
correctly detected. The following example compiles without error in Visual Studio 2017,
but in Visual Studio 2019 under /std:c++17 mode or later it raises error C2248:

C++
struct X
{
private:
static inline const int c = 1000;
};

struct Y : X
{
static inline int d = c; // VS2019 C2248: cannot access private member
declared in class 'X'.
};

To avoid the error, declare the member X::c as protected:

C++

struct X
{
protected:
static inline const int c = 1000;
};

C4800 reinstated
MSVC used to have a performance warning C4800 about implicit conversion to bool . It
was too noisy and couldn't be suppressed, leading us to remove it in Visual Studio 2017.
However, over the lifecycle of Visual Studio 2017 we got lots of feedback on the useful
cases it was solving. We bring back in Visual Studio 2019 a carefully tailored C4800,
along with the explanatory C4165. Both of these warnings are easy to suppress: either
by using an explicit cast, or by comparison to 0 of the appropriate type. C4800 is an off-
by-default level 4 warning, and C4165 is an off-by-default level 3 warning. Both are
discoverable by using the /Wall compiler option.

The following example raises C4800 and C4165 under /Wall :

C++

bool test(IUnknown* p)
{
bool valid = p; // warning C4800: Implicit conversion from 'IUnknown*'
to bool. Possible information loss
IDispatch* d = nullptr;
HRESULT hr = p->QueryInterface(__uuidof(IDispatch),
reinterpret_cast<void**>(&d));
return hr; // warning C4165: 'HRESULT' is being converted to 'bool'; are
you sure this is what you want?
}

To avoid the warnings in the previous example, you can write the code like this:

C++

bool test(IUnknown* p)
{
bool valid = p != nullptr; // OK
IDispatch* d = nullptr;
HRESULT hr = p->QueryInterface(__uuidof(IDispatch),
reinterpret_cast<void**>(&d));
return SUCCEEDED(hr); // OK
}

Local class member function doesn't have a body


In Visual Studio 2017, warning C4822 is raised only when compiler option /w14822 is
explicitly set. It isn't shown with /Wall . In Visual Studio 2019, C4822 is an off-by-default
warning, which makes it discoverable under /Wall without having to set /w14822
explicitly.

C++

void example()
{
struct A
{
int boo(); // warning C4822: Local class member function doesn't
have a body
};
}

Function template bodies containing if constexpr


statements
In Visual Studio 2019 under /std:c++20 or /std:c++latest , template function bodies
that have if constexpr statements have extra parsing-related checks enabled. For
example, in Visual Studio 2017 the following code produces C7510 only if the
/permissive- option is set. In Visual Studio 2019 the same code raises errors even when

the /permissive option is set:

C++
// C7510.cpp
// compile using: cl /EHsc /W4 /permissive /std:c++latest C7510.cpp
#include <iostream>

template <typename T>


int f()
{
T::Type a; // error C7510: 'Type': use of dependent type name must be
prefixed with 'typename'
// To fix the error, add the 'typename' keyword. Use this declaration
instead:
// typename T::Type a;

if constexpr (a.val)
{
return 1;
}
else
{
return 2;
}
}

struct X
{
using Type = X;
constexpr static int val = 1;
};

int main()
{
std::cout << f<X>() << "\n";
}

To avoid the error, add the typename keyword to the declaration of a : typename T::Type
a; .

Inline assembly code isn't supported in a lambda


expression
The Microsoft C++ team was recently made aware of a security issue in which the use of
inline-assembler within a lambda could lead to the corruption of ebp (the return
address register) at runtime. A malicious attacker could possibly take advantage of this
scenario. The inline assembler is only supported on x86, and interaction between the
inline assembler and the rest of the compiler is poor. Given these facts and the nature of
the issue, the safest solution to this problem was to disallow inline assembler within a
lambda expression.
The only use of inline assembler within a lambda expression that we have found 'in the
wild' was to capture the return address. In this scenario, you can capture the return
address on all platforms simply by using a compiler intrinsic _ReturnAddress() .

The following code produces C7553 in Visual Studio 2017 15.9 and later versions of
Visual Studio:

C++

#include <cstdio>

int f()
{
int y = 1724;
int x = 0xdeadbeef;

auto lambda = [&]


{
__asm { // C7553: inline assembler is not supported in a lambda

mov eax, x
mov y, eax
}
};

lambda();
return y;
}

To avoid the error, move the assembly code into a named function as shown in the
following example:

C++

#include <cstdio>

void g(int& x, int& y)


{
__asm {
mov eax, x
mov y, eax
}
}

int f()
{
int y = 1724;
int x = 0xdeadbeef;
auto lambda = [&]
{
g(x, y);
};
lambda();
return y;
}

int main()
{
std::printf("%d\n", f());
}

Iterator debugging and std::move_iterator


The iterator debugging feature has been taught to properly unwrap
std::move_iterator . For example,

std::copy(std::move_iterator<std::vector<int>::iterator>,

std::move_iterator<std::vector<int>::iterator>, int*) can now engage the memcpy


fast path.

Fixes for <xkeycheck.h> keyword enforcement


The standard library's enforcement in <xkeycheck.h> for macros replacing a keyword
was fixed. The library now emits the actual problem keyword detected rather than a
generic message. It also supports C++20 keywords, and avoids tricking IntelliSense into
saying random keywords are macros.

Allocator types no longer deprecated


std::allocator<void> , std::allocator::size_type , and
std::allocator::difference_type are no longer deprecated.

Correct warning for narrowing string conversions


Removed a spurious static_cast from std::string that wasn't called for by the
standard, and that accidentally suppressed C4244 narrowing warnings. Attempts to call
std::string::string(const wchar_t*, const wchar_t*) now properly emit C4244 about

narrowing a wchar_t into a char .

Various fixes for <filesystem> correctness


Fixed std::filesystem::last_write_time failing when attempting to change a
directory's last write time.
The std::filesystem::directory_entry constructor now stores a failed result,
rather than throwing an exception, when supplied a nonexistent target path.
The std::filesystem::create_directory 2-parameter version was changed to call
the 1-parameter version, as the underlying CreateDirectoryExW function would use
copy_symlink when the existing_p was a symlink.

std::filesystem::directory_iterator no longer fails when a broken symlink is

found.
std::filesystem::space now accepts relative paths.
std::filesystem::path::lexically_relative is no longer confused by trailing

slashes, reported as LWG 3096 .


Worked around CreateSymbolicLinkW rejecting paths with forward slashes in
std::filesystem::create_symlink .

Worked around the POSIX deletion mode delete function that existed in Windows
10 LTSB 1609, but couldn't actually delete files.
The std::boyer_moore_searcher and std::boyer_moore_horspool_searcher copy
constructors and copy assignment operators now actually copy things.

Parallel algorithms on Windows 8 and later


The parallel algorithms library now properly uses the real WaitOnAddress family on
Windows 8 and later, rather than always using the Windows 7 and earlier fake versions.

std::system_category::message() whitespace

std::system_category::message() now trims trailing whitespace from the returned

message.

std::linear_congruential_engine divide by zero

Some conditions that would cause std::linear_congruential_engine to trigger divide by


0 have been fixed.

Fixes for iterator unwrapping


Some iterator-unwrapping machinery was first exposed for programmer-user
integration in Visual Studio 2017 15.8. It was described in C++ Team Blog article STL
Features and Fixes in VS 2017 15.8 . This machinery no longer unwraps iterators
derived from standard library iterators. For example, a user that derives from
std::vector<int>::iterator and tries to customize behavior now gets their customized

behavior when calling standard library algorithms, rather than the behavior of a pointer.

The unordered container reserve function now actually reserves for N elements, as
described in LWG 2156 .

Time handling
Previously, some time values that were passed to the concurrency library would
overflow, for example, condition_variable::wait_for(seconds::max()) . Now fixed,
the overflows changed behavior on a seemingly random 29-day cycle (when
uint32_t milliseconds accepted by underlying Win32 APIs overflowed).

The <ctime> header now correctly declares timespec and timespec_get in


namespace std , and also declares them in the global namespace.

Various fixes for containers


Many standard library internal container functions have been made private for an
improved IntelliSense experience. More fixes to mark members as private are
expected in later releases of MSVC.

We fixed exception safety correctness problems that caused node-based


containers, such as list , map , and unordered_map , to become corrupted. During a
propagate_on_container_copy_assignment or

propagate_on_container_move_assignment reassignment operation, we would free

the container's sentinel node with the old allocator, do the POCCA/POCMA
assignment over the old allocator, and then try to acquire the sentinel node from
the new allocator. If this allocation failed, the container was corrupted. It couldn't
even be destroyed, as owning a sentinel node is a hard data structure invariant.
This code was fixed to create the new sentinel node by using the source
container's allocator before destroying the existing sentinel node.

The containers were fixed to always copy/move/swap allocators according to


propagate_on_container_copy_assignment ,
propagate_on_container_move_assignment , and propagate_on_container_swap , even

for allocators declared is_always_equal .

Added the overloads for container merge and extract member functions that
accept rvalue containers. For more information, see P0083 "Splicing Maps And
Sets"
std::basic_istream::read processing of \r\n => \n

std::basic_istream::read was fixed to not write into parts of the supplied buffer

temporarily as part of \r\n to \n processing. This change gives up some of the


performance advantage that was gained in Visual Studio 2017 15.8 for reads larger than
4K in size. However, efficiency improvements from avoiding three virtual calls per
character are still present.

std::bitset constructor

The std::bitset constructor no longer reads the ones and zeroes in reverse order for
large bitsets.

std::pair::operator= regression

We fixed a regression in the std::pair assignment operator introduced when


implementing LWG 2729 "Missing SFINAE on std::pair::operator="; . It now correctly
accepts types convertible to std::pair again.

Non-deduced contexts for add_const_t


We fixed a minor type traits bug, where add_const_t and related functions are supposed
to be a non-deduced context. In other words, add_const_t should be an alias for
typename add_const<T>::type , not const T .

Conformance improvements in 16.1

char8_t
P0482r6 . C++20 adds a new character type that is used to represent UTF-8 code units.
u8 string literals in C++20 have type const char8_t[N] instead of const char[N] , which

was the case previously. Similar changes have been proposed for the C standard in
N2231 . Suggestions for char8_t backward compatibility remediation are given in
P1423r3 . The Microsoft C++ compiler adds support for char8_t in Visual Studio 2019
version 16.1 when you specify the /Zc:char8_t compiler option. It can be reverted to
C++17 behavior via /Zc:char8_t- . The EDG compiler that powers IntelliSense doesn't
yet support it in Visual Studio 2019 version 16.1. You may see spurious IntelliSense-only
errors that don't affect the actual compilation.
Example

C++

const char* s = u8"Hello"; // C++17


const char8_t* s = u8"Hello"; // C++20

std::type_identity metafunction and std::identity


function object
P0887R1 type_identity . The deprecated std::identity class template extension has
been removed, and replaced with the C++20 std::type_identity metafunction and
std::identity function object. Both are available only under /std:c++latest

( /std:c++20 in Visual Studio 2019 version 16.11 and later).

The following example produces deprecation warning C4996 for std::identity (defined
in <type_traits>) in Visual Studio 2017:

C++

#include <type_traits>

using T = std::identity<int>::type;
T x, y = std::identity<T>{}(x);
int i = 42;
long j = std::identity<long>{}(i);

The following example shows how to use the new std::identity (defined in
<functional>) together with the new std::type_identity :

C++

#include <type_traits>
#include <functional>

using T = std::type_identity<int>::type;
T x, y = std::identity{}(x);
int i = 42;
long j = static_cast<long>(i);

Syntax checks for generic lambdas


The new lambda processor enables some conformance-mode syntactic checks in
generic lambdas, under /std:c++latest ( /std:c++20 in Visual Studio 2019 version 16.11
and later) or under any other language mode with /Zc:lambda in Visual Studio 2019
version 16.9 or later (previously available as /experimental:newLambdaProcessor
beginning in Visual Studio 2019 version 16.3).

The legacy lambda processor compiles this example without warnings, but the new
lambda processor produces error C2760:

C++

void f() {
auto a = [](auto arg) {
decltype(arg)::Type t; // C2760 syntax error: unexpected token
'identifier', expected ';'
};
}

This example shows the correct syntax, now enforced by the compiler:

C++

void f() {
auto a = [](auto arg) {
typename decltype(arg)::Type t;
};
}

Argument-dependent lookup for function calls


P0846R0 (C++20) Increased ability to find function templates via argument-
dependent lookup for function-call expressions with explicit template arguments.
Requires /std:c++latest (or /std:c++20 in Visual Studio 2019 version 16.11 and later).

Designated initialization
P0329R4 (C++20) Designated initialization allows specific members to be selected in
aggregate initialization by using the Type t { .member = expr } syntax. Requires
/std:c++latest (or /std:c++20 in Visual Studio 2019 version 16.11 and later).

Ranking of enum conversion to its fixed underlying type


The compiler now ranks enum conversions according to N4800 11.3.3.2 Ranking
implicit conversion sequences (4.2):

A conversion that promotes an enumeration whose underlying type is fixed to its


underlying type is better than one that promotes to the promoted underlying type,
if the two are different.

This conversion ranking wasn't implemented correctly before Visual Studio 2019 version
16.1. The conforming behavior may change overload resolution behavior or expose an
ambiguity where one previously wasn't detected.

This compiler behavior change applies to all /std modes and is both a source and
binary breaking change.

The following example demonstrates how compiler behavior changes in 16.1 and later
versions:

C++

#include <type_traits>

enum E : unsigned char { e };

int f(unsigned int)


{
return 1;
}

int f(unsigned char)


{
return 2;
}

struct A {};
struct B : public A {};

int f(unsigned int, const B&)


{
return 3;
}

int f(unsigned char, const A&)


{
return 4;
}

int main()
{
// Calls f(unsigned char) in 16.1 and later. Called f(unsigned int) in
earlier versions.
// The conversion from 'E' to the fixed underlying type 'unsigned char'
is better than the
// conversion from 'E' to the promoted type 'unsigned int'.
f(e);

// Error C2666. This call is ambiguous, but previously called f(unsigned


int, const B&).
f(e, B{});
}

New and updated standard library functions (C++20)


starts_with() and ends_with() for basic_string and basic_string_view .

contains() for associative containers.

remove() , remove_if() , and unique() for list and forward_list now return
size_type .

shift_left() and shift_right() added to <algorithm>.

Conformance improvements in 16.2

noexcept constexpr functions

constexpr functions are no longer considered noexcept by default when used in a

constant expression. This behavior change comes from the resolution of Core Working
Group (CWG) CWG 1351 and is enabled in /permissive-. The following example
compiles in Visual Studio 2019 version 16.1 and earlier, but produces C2338 in Visual
Studio 2019 version 16.2:

C++

constexpr int f() { return 0; }

int main() {
static_assert(noexcept(f()), "f should be noexcept"); // C2338 in 16.2
}

To fix the error, add the noexcept expression to the function declaration:

C++

constexpr int f() noexcept { return 0; }

int main() {
static_assert(noexcept(f()), "f should be noexcept");
}

Binary expressions with different enum types


C++20 has deprecated the usual arithmetic conversions on operands, where:

One operand is of enumeration type, and

the other is of a different enumeration type or a floating-point type.

For more information, see P1120R0 .

In Visual Studio 2019 version 16.2 and later, the following code produces a level 4 C5054
warning when the /std:c++latest compiler option is enabled ( /std:c++20 in Visual
Studio 2019 version 16.11 and later):

C++

enum E1 { a };
enum E2 { b };
int main() {
int i = a | b; // warning C5054: operator '|': deprecated between
enumerations of different types
}

To avoid the warning, use static_cast to convert the second operand:

C++

enum E1 { a };
enum E2 { b };
int main() {
int i = a | static_cast<int>(b);
}

Using a binary operation between an enumeration and a floating-point type is now a


level 1 C5055 warning when the /std:c++latest compiler option is enabled ( /std:c++20
in Visual Studio 2019 version 16.11 and later):

C++

enum E1 { a };
int main() {
double i = a * 1.1;
}

To avoid the warning, use static_cast to convert the second operand:

C++

enum E1 { a };
int main() {
double i = static_cast<int>(a) * 1.1;
}

Equality and relational comparisons of arrays


Equality and relational comparisons between two operands of array type are deprecated
in C++20 (P1120R0 ). In other words, a comparison operation between two arrays
(despite rank and extent similarities) is now a warning. In Visual Studio 2019 version 16.2
and later, the following code produces level 1 warning C5056 when the /std:c++latest
compiler option is enabled ( /std:c++20 in Visual Studio 2019 version 16.11 and later):

C++

int main() {
int a[] = { 1, 2, 3 };
int b[] = { 1, 2, 3 };
if (a == b) { return 1; } // warning C5056: operator '==': deprecated
for array types
}

To avoid the warning, you can compare the addresses of the first elements:

C++

int main() {
int a[] = { 1, 2, 3 };
int b[] = { 1, 2, 3 };
if (&a[0] == &b[0]) { return 1; }
}

To determine whether the contents of two arrays are equal, use the std::equal function:

C++

std::equal(std::begin(a), std::end(a), std::begin(b), std::end(b));


Effect of defining spaceship operator on == and !=
A definition of the spaceship operator ( <=> ) alone will no longer rewrite expressions
involving == or != unless the spaceship operator is marked as = default (P1185R2 ).
The following example compiles in Visual Studio 2019 RTW and version 16.1, but
produces C2678 in Visual Studio 2019 version 16.2:

C++

#include <compare>

struct S {
int a;
auto operator<=>(const S& rhs) const {
return a <=> rhs.a;
}
};
bool eq(const S& lhs, const S& rhs) {
return lhs == rhs; // error C2676
}
bool neq(const S& lhs, const S& rhs) {
return lhs != rhs; // error C2676
}

To avoid the error, define operator== or declare it as defaulted:

C++

#include <compare>

struct S {
int a;
auto operator<=>(const S& rhs) const {
return a <=> rhs.a;
}
bool operator==(const S&) const = default;
};
bool eq(const S& lhs, const S& rhs) {
return lhs == rhs;
}
bool neq(const S& lhs, const S& rhs) {
return lhs != rhs;
}

Standard Library improvements


<charconv> to_chars() with fixed/scientific precision. (General precision is
currently planned for 16.4.)
P0020R6 : atomic<float> , atomic<double> , atomic<long double>
P0463R1 : endian
P0482R6 : Library Support For char8_t
P0600R1 : [[nodiscard]] For The STL, Part 1
P0653R2 : to_address()
P0754R2 : <version>
P0771R1 : noexcept For std::function 's move constructor

Const comparators for associative containers


Code for search and insertion in set, map, multiset, and multimap has been merged for
reduced code size. Insertion operations now call the less-than comparison on a const
comparison functor, in the same way that search operations have done previously. The
following code compiles in Visual Studio 2019 version 16.1 and earlier, but raises C3848
in Visual Studio 2019 version 16.2:

C++

#include <iostream>
#include <map>

using namespace std;

struct K
{
int a;
string b = "label";
};

struct Comparer {
bool operator() (K a, K b) {
return a.a < b.a;
}
};

map<K, double, Comparer> m;

K const s1{1};
K const s2{2};
K const s3{3};

int main() {

m.emplace(s1, 1.08);
m.emplace(s2, 3.14);
m.emplace(s3, 5.21);
}

To avoid the error, make the comparison operator const :

C++

struct Comparer {
bool operator() (K a, K b) const {
return a.a < b.a;
}
};

Conformance improvements in Visual Studio


2019 version 16.3

Stream extraction operators for char* removed


Stream extraction operators for pointer-to-characters have been removed and replaced
by extraction operators for array-of-characters (per P0487R1 ). WG21 considers the
removed overloads to be unsafe. In /std:c++20 or /std:c++latest mode, the following
example now produces C2679:

C++

// stream_extraction.cpp
// compile by using: cl /std:c++latest stream_extraction.cpp

#include <iostream>
#include <iomanip>

int main() {
char x[42];
char* p = x;
std::cin >> std::setw(42);
std::cin >> p; // C2679: binary '>>': no operator found which takes a
right-hand operand of type 'char *' (or there is no acceptable conversion)
}

To avoid the error, use the extraction operator with a char[] variable:

C++

#include <iostream>
#include <iomanip>
int main() {
char x[42];
std::cin >> std::setw(42);
std::cin >> x; // OK
}

New keywords requires and concept


New keywords requires and concept have been added to the Microsoft C++ compiler.
If you attempt to use either one as an identifier in /std:c++20 or /std:c++latest mode,
the compiler raises C2059 to indicate a syntax error.

Constructors as type names disallowed


The compiler no longer considers constructor names as injected-class-names in this
case: when they appear in a qualified name after an alias to a class-template
specialization. Previously, constructors were usable as a type name to declare other
entities. The following example now produces C3646:

C++

#include <chrono>

class Foo {
std::chrono::milliseconds::duration TotalDuration{}; // C3646:
'TotalDuration': unknown override specifier
};

To avoid the error, declare TotalDuration as shown here:

C++

#include <chrono>

class Foo {
std::chrono::milliseconds TotalDuration {};
};

Stricter checking of extern "C" functions


If an extern "C" function was declared in different namespaces, previous versions of the
Microsoft C++ compiler didn't check whether the declarations were compatible. In
Visual Studio 2019 version 16.3 and later, the compiler checks for compatibility. In
/permissive- mode, the following code produces errors C2371 and C2733:

C++

using BOOL = int;

namespace N
{
extern "C" void f(int, int, int, bool);
}

void g()
{
N::f(0, 1, 2, false);
}

extern "C" void f(int, int, int, BOOL){}


// C2116: 'N::f': function parameter lists do not match between
declarations
// C2733: 'f': you cannot overload a function with 'extern "C"' linkage

To avoid the errors in the previous example, use bool instead of BOOL consistently in
both declarations of f .

Standard Library improvements


The non-standard headers <stdexcpt.h> and <typeinfo.h> have been removed. Code
that includes them should instead include the standard headers <exception> and
<typeinfo>, respectively.

Conformance improvements in Visual Studio


2019 version 16.4

Better enforcement of two-phase name lookup for


qualified-ids in /permissive-
Two-phase name lookup requires that non-dependent names used in template bodies
must be visible to the template at definition time. Previously, such names may have
been found when the template is instantiated. This change makes it easier to write
portable and conforming code in MSVC under the /permissive- flag.
In Visual Studio 2019 version 16.4 with the /permissive- flag set, the following example
produces an error, because N::f isn't visible when the f<T> template is defined:

C++

template <class T>


int f() {
return N::f() + T{}; // error C2039: 'f': is not a member of 'N'
}

namespace N {
int f() { return 42; }
}

Typically, this error can be fixed by including missing headers or forward-declaring


functions or variables, as shown in the following example:

C++

namespace N {
int f();
}

template <class T>


int f() {
return N::f() + T{};
}

namespace N {
int f() { return 42; }
}

Implicit conversion of integral constant expressions to


null pointer
The MSVC compiler now implements CWG Issue 903 in conformance mode
( /permissive- ). This rule disallows implicit conversion of integral constant expressions
(except for the integer literal '0') to null pointer constants. The following example
produces C2440 in conformance mode:

C++

int* f(bool* p) {
p = false; // error C2440: '=': cannot convert from 'bool' to 'bool *'
p = 0; // OK
return false; // error C2440: 'return': cannot convert from 'bool' to
'int *'
}

To fix the error, use nullptr instead of false . A literal 0 is still allowed:

C++

int* f(bool* p) {
p = nullptr; // OK
p = 0; // OK
return nullptr; // OK
}

Standard rules for types of integer literals


In conformance mode (enabled by /permissive-), MSVC uses the standard rules for types
of integer literals. Decimal literals too large to fit in a signed int were previously given
type unsigned int . Now such literals are given the next largest signed integer type,
long long . Additionally, literals with the 'll' suffix that are too large to fit in a signed

type are given type unsigned long long .

This change can lead to different warning diagnostics being generated, and behavior
differences for arithmetic operations on literals.

The following example shows the new behavior in Visual Studio 2019 version 16.4. The
i variable is now of type unsigned int , so the warning is raised. The high-order bits of

the variable j are set to 0.

C++

void f(int r) {
int i = 2964557531; // warning C4309: truncation of constant value
long long j = 0x8000000000000000ll >> r; // literal is now unsigned,
shift will fill high-order bits with 0
}

The following example demonstrates how to keep the old behavior and avoid the
warnings and run-time behavior change:

C++

void f(int r) {
int i = 2964557531u; // OK
long long j = (long long)0x8000000000000000ll >> r; // shift will keep high-
order bits
}

Function parameters that shadow template parameters


The MSVC compiler now raises an error when a function parameter shadows a template
parameter:

C++

template<typename T>
void f(T* buffer, int size, int& size_read);

template<typename T, int Size>


void f(T(&buffer)[Size], int& Size) // error C7576: declaration of 'Size'
shadows a template parameter
{
return f(buffer, Size, Size);
}

To fix the error, change the name of one of the parameters:

C++

template<typename T>
void f(T* buffer, int size, int& size_read);

template<typename T, int Size>


void f(T (&buffer)[Size], int& size_read)
{
return f(buffer, Size, size_read);
}

User-provided specializations of type traits


In conformance with the meta.rqmts subclause of the Standard, the MSVC compiler now
raises an error when it finds a user-defined specialization of one of the specified
type_traits templates in the std namespace. Unless otherwise specified, such

specializations result in undefined behavior. The following example has undefined


behavior because it violates the rule, and the static_assert fails with error C2338.

C++

#include <type_traits>
struct S;
template<>
struct std::is_fundamental<S> : std::true_type {};

static_assert(std::is_fundamental<S>::value, "fail");

To avoid the error, define a struct that inherits from the preferred type_trait , and
specialize that:

C++

#include <type_traits>

struct S;

template<typename T>
struct my_is_fundamental : std::is_fundamental<T> {};

template<>
struct my_is_fundamental<S> : std::true_type { };

static_assert(my_is_fundamental<S>::value, "fail");

Changes to compiler-provided comparison operators


The MSVC compiler now implements the following changes to comparison operators
per P1630R1 when the /std:c++20 or /std:c++latest option is enabled:

The compiler no longer rewrites expressions using operator== if they involve a return
type that isn't a bool . The following code now produces error C2088:

C++

struct U {
operator bool() const;
};

struct S {
U operator==(const S&) const;
};

bool neq(const S& lhs, const S& rhs) {


return lhs != rhs; // C2088: '!=': illegal for struct
}

To avoid the error, you must explicitly define the needed operator:

C++
struct U {
operator bool() const;
};

struct S {
U operator==(const S&) const;
U operator!=(const S&) const;
};

bool neq(const S& lhs, const S& rhs) {


return lhs != rhs;
}

The compiler no longer defines a defaulted comparison operator if it's a member of a


union-like class. The following example now produces error C2120:

C++

#include <compare>

union S {
int a;
char b;
auto operator<=>(const S&) const = default;
};

bool lt(const S& lhs, const S& rhs) {


return lhs < rhs;
}

To avoid the error, define a body for the operator:

C++

#include <compare>

union S {
int a;
char b;
auto operator<=>(const S&) const { ... }
};

bool lt(const S& lhs, const S& rhs) {


return lhs < rhs;
}

The compiler will no longer define a defaulted comparison operator if the class contains
a reference member. The following code now produces error C2120:
C++

#include <compare>

struct U {
int& a;
auto operator<=>(const U&) const = default;
};

bool lt(const U& lhs, const U& rhs) {


return lhs < rhs;
}

To avoid the error, define a body for the operator:

C++

#include <compare>

struct U {
int& a;
auto operator<=>(const U&) const { ... };
};

bool lt(const U& lhs, const U& rhs) {


return lhs < rhs;
}

Conformance improvements in Visual Studio


2019 version 16.5

Explicit specialization declaration without an initializer


isn't a definition
Under /permissive- , MSVC now enforces a standard rule that explicit specialization
declarations without initializers aren't definitions. Previously, the declaration would be
considered a definition with a default-initializer. The effect is observable at link time,
since a program depending on this behavior may now have unresolved symbols. This
example now results in an error:

C++

template <typename> struct S {


static int a;
};
// In permissive-, this declaration isn't a definition, and the program
won't link.
template <> int S<char>::a;

int main() {
return S<char>::a;
}

Output

error LNK2019: unresolved external symbol "public: static int S<char>::a" (?


a@?$S@D@@2HA) referenced in function _main at link time.

To resolve the issue, add an initializer:

C++

template <typename> struct S {


static int a;
};

// Add an initializer for the declaration to be a definition.


template <> int S<char>::a{};

int main() {
return S<char>::a;
}

Preprocessor output preserves newlines


The experimental preprocessor now preserves newlines and whitespace when using /P
or /E with /experimental:preprocessor .

Given this example source,

C++

#define m()
line m(
) line

The previous output of /E was:

Output
line line
#line 2

The new output of /E is now:

Output

line
line

import and module keywords are context-dependent

Per P1857R1 , import and module preprocessor directives have new restrictions on
their syntax. This example no longer compiles:

C++

import // Invalid
m; // error C2146: syntax error: missing ';' before identifier 'm'

To resolve the issue, keep the import on the same line:

C++

import m; // OK

Removal of std::weak_equality and std::strong_equality


The merge of P1959R0 requires the compiler to remove behavior and references to
the std::weak_equality and std::strong_equality types.

The code in this example no longer compiles:

C++

#include <compare>

struct S {
std::strong_equality operator<=>(const S&) const = default;
};

void f() {
nullptr<=>nullptr;
&f <=> &f;
&S::operator<=> <=> &S::operator<=>;
}

The example now leads to these errors:

Output

error C2039: 'strong_equality': is not a member of 'std'


error C2143: syntax error: missing ';' before '<=>'
error C4430: missing type specifier - int assumed. Note: C++ does not
support default-int
error C4430: missing type specifier - int assumed. Note: C++ does not
support default-int
error C7546: binary operator '<=>': unsupported operand types 'nullptr' and
'nullptr'
error C7546: binary operator '<=>': unsupported operand types 'void (__cdecl
*)(void)' and 'void (__cdecl *)(void)'
error C7546: binary operator '<=>': unsupported operand types 'int
(__thiscall S::* )(const S &) const' and 'int (__thiscall S::* )(const S &)
const'

To resolve the issue, update to prefer the built-in relational operators and replace the
removed types:

C++

#include <compare>

struct S {
std::strong_ordering operator<=>(const S&) const = default; // prefer
'std::strong_ordering'
};

void f() {
nullptr != nullptr; // use pre-existing builtin operator != or ==.
&f != &f;
&S::operator<=> != &S::operator<=>;
}

TLS Guard changes


Previously, thread-local variables in DLLs weren't correctly initialized. Other than on the
thread that loaded the DLL, they weren't initialized before first use on threads that
existed before the DLL was loaded. This defect has now been corrected. Thread-local
variables in such a DLL get initialized immediately before their first use on such threads.
This new behavior of testing for initialization on uses of thread-local variables may be
disabled by using the /Zc:tlsGuards- compiler option. Or, by adding the
[[msvc:no_tls_guard]] attribute to particular thread local variables.

Better diagnosis of call to deleted functions


Our compiler was more permissive about calls to deleted functions previously. For
example, if the calls happened in the context of a template body, we wouldn't diagnose
the call. Additionally, if there were multiple instances of calls to deleted functions, we
would only issue one diagnostic. Now we issue a diagnostic for each of them.

One consequence of the new behavior can produce a small breaking change: Code that
called a deleted function wouldn't get diagnosed if it was never needed for code
generation. Now we diagnose it up front.

This example shows code that now produces an error:

C++

struct S {
S() = delete;
S(int) { }
};

struct U {
U() = delete;
U(int i): s{ i } { }

S s{};
};

U u{ 0 };

Output

error C2280: 'S::S(void)': attempting to reference a deleted function


note: see declaration of 'S::S'
note: 'S::S(void)': function was explicitly deleted

To resolve the issue, remove calls to deleted functions:

C++

struct S {
S() = delete;
S(int) { }
};
struct U {
U() = delete;
U(int i): s{ i } { }

S s; // Do not call the deleted ctor of 'S'.


};

U u{ 0 };

Conformance improvements in Visual Studio


2019 version 16.6

Standard library streams reject insertions of mis-encoded


character types
Traditionally, inserting a wchar_t into a std::ostream , and inserting char16_t or
char32_t into a std::ostream or std::wostream , outputs its integral value. Inserting

pointers to those character types outputs the pointer value. Programmers don't find
either case intuitive. They often expect the standard library to transcode the character or
null-terminated character string instead, and to output the result.

The C++20 proposal P1423R3 adds deleted stream insertion operator overloads for
these combinations of stream and character or character pointer types. Under
/std:c++20 or /std:c++latest , the overloads make these insertions ill-formed, instead

of behaving in what is likely an unintended manner. The compiler raises error C2280
when one is found. You can define the "escape hatch" macro
_HAS_STREAM_INSERTION_OPERATORS_DELETED_IN_CXX20 to 1 to restore the old behavior.

(The proposal also deletes stream insertion operators for char8_t . Our standard library
implemented similar overloads when we added char8_t support, so the "wrong"
behavior has never been available for char8_t .)

This sample shows the behavior with this change:

C++

#include <iostream>
int main() {
const wchar_t cw = L'x', *pw = L"meow";
const char16_t c16 = u'x', *p16 = u"meow";
const char32_t c32 = U'x', *p32 = U"meow";
std::cout << cw << ' ' << pw << '\n';
std::cout << c16 << ' ' << p16 << '\n';
std::cout << c32 << ' ' << p32 << '\n';
std::wcout << c16 << ' ' << p16 << '\n';
std::wcout << c32 << ' ' << p32 << '\n';
}

The code now produces these diagnostic messages:

Output

error C2280: 'std::basic_ostream<char,std::char_traits<char>> &std::


<<<std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>>
&,wchar_t)': attempting to reference a deleted function
error C2280: 'std::basic_ostream<char,std::char_traits<char>> &std::
<<<std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>>
&,char16_t)': attempting to reference a deleted function
error C2280: 'std::basic_ostream<char,std::char_traits<char>> &std::
<<<std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>>
&,char32_t)': attempting to reference a deleted function
error C2280: 'std::basic_ostream<wchar_t,std::char_traits<wchar_t>> &std::
<<<std::char_traits<wchar_t>>
(std::basic_ostream<wchar_t,std::char_traits<wchar_t>> &,char16_t)':
attempting to reference a deleted function
error C2280: 'std::basic_ostream<wchar_t,std::char_traits<wchar_t>> &std::
<<<std::char_traits<wchar_t>>
(std::basic_ostream<wchar_t,std::char_traits<wchar_t>> &,char32_t)':
attempting to reference a deleted function

You can achieve the effect of the old behavior in all language modes by converting
character types to unsigned int , or pointer-to-character types to const void* :

C++

#include <iostream>
int main() {
const wchar_t cw = L'x', *pw = L"meow";
const char16_t c16 = u'x', *p16 = u"meow";
const char32_t c32 = U'x', *p32 = U"meow";
std::cout << (unsigned)cw << ' ' << (const void*)pw << '\n'; // Outputs
"120 0052B1C0"
std::cout << (unsigned)c16 << ' ' << (const void*)p16 << '\n'; //
Outputs "120 0052B1CC"
std::cout << (unsigned)c32 << ' ' << (const void*)p32 << '\n'; //
Outputs "120 0052B1D8"
std::wcout << (unsigned)c16 << ' ' << (const void*)p16 << '\n'; //
Outputs "120 0052B1CC"
std::wcout << (unsigned)c32 << ' ' << (const void*)p32 << '\n'; //
Outputs "120 0052B1D8"
}
Changed return type of std::pow() for std::complex
Previously, the MSVC implementation of the promotion rules for the return type of
function template std::pow() was incorrect. For example, previously
pow(complex<float>, int) returned complex<float> . Now it correctly returns

complex<double> . The fix has been implemented unconditionally for all standards modes

in Visual Studio 2019 version 16.6.

This change can cause compiler errors. For example, previously you could multiply
pow(complex<float>, int) by a float . Because complex<T> operator* expects

arguments of the same type, the following example now emits compiler error C2676:

C++

// pow_error.cpp
// compile by using: cl /EHsc /nologo /W4 pow_error.cpp
#include <complex>

int main() {
std::complex<float> cf(2.0f, 0.0f);
(void) (std::pow(cf, -1) * 3.0f);
}

Output

pow_error.cpp(7): error C2676: binary '*': 'std::complex<double>' does not


define this operator or a conversion to a type acceptable to the predefined
operator

There are many possible fixes:

Change the type of the float multiplicand to double . This argument can be
converted directly to a complex<double> to match the type returned by pow .

Narrow the result of pow to complex<float> by saying complex<float>{pow(ARG,


ARG)} . Then you can continue to multiply by a float value.

Pass float instead of int to pow . This operation may be slower.

In some cases, you can avoid pow entirely. For example, pow(cf, -1) can be
replaced by division.

switch warnings for C


In Visual Studio 2019 version 16.6 and later, the compiler implements some preexisting
C++ warnings for code compiled as C. The following warnings are now enabled at
different levels: C4060, C4061, C4062, C4063, C4064, C4065, C4808, and C4809.
Warnings C4065 and C4060 are disabled by default in C.

The warnings trigger on missing case statements, undefined enum , and bad bool switch
statements (that is, ones that contain too many cases). For example:

#include <stdbool.h>

int main() {
bool b = true;
switch (b) {
case true: break;
case false: break;
default: break; // C4809: switch statement has redundant 'default'
label;
// all possible 'case' labels are given
}
}

To fix this code, remove the redundant default case:

#include <stdbool.h>

int main() {
bool b = true;
switch (b) {
case true: break;
case false: break;
}
}

Unnamed classes in typedef declarations


In Visual Studio 2019 version 16.6 and later, the behavior of typedef declarations has
been restricted to conform to P1766R1 . With this update, unnamed classes within a
typedef declaration can't have any members other than:

non-static data members with no default member initializers,


member classes, or
member enumerations.
The same restrictions are applied recursively to each nested class. The restriction is
meant to ensure the simplicity of structs that have typedef names for linkage purposes.
They must be simple enough that no linkage calculations are necessary before the
compiler gets to the typedef name for linkage.

This change affects all standards modes of the compiler. In default ( /std:c++14 ) and
/std:c++17 modes, the compiler emits warning C5208 for non-conforming code. If
/permissive- is specified, the compiler emits warning C5208 as an error under

/std:c++14 and emits error C7626 under /std:c++17 . The compiler emits error C7626

for non-conforming code when /std:c++20 or /std:c++latest is specified.

The following sample shows the constructs that are no longer allowed in unnamed
structs. Depending on the standards mode specified, C5208 or C7626 errors or warnings
are emitted:

C++

struct B { };
typedef struct : B { // inheriting from 'B'; ill-formed
void f(); // ill-formed
static int i; // ill-formed
struct U {
void f(); // nested class has non-data member; ill-formed
};
int j = 10; // default member initializer; ill-formed
} S;

The code above can be fixed by giving the unnamed class a name:

C++

struct B { };
typedef struct S_ : B {
void f();
static int i;
struct U {
void f();
};
int j = 10;
} S;

Default argument import in C++/CLI


An increasing number of APIs have default arguments in .NET Core. So, we now support
default argument import in C++/CLI. This change can break existing code where
multiple overloads are declared, as in this example:

C++

public class R {
public void Func(string s) {} // overload 1
public void Func(string s, string s2 = "") {} // overload 2;
}

When this class is imported into C++/CLI, a call to one of the overloads causes an error:

C++

(gcnew R)->Func("abc"); // error C2668: 'R::Func' ambiguous call to


overloaded function

The compiler emits error C2668 because both overloads match this argument list. In the
second overload, the second argument is filled in by the default argument. To work
around this problem, you can delete the redundant overload (1). Or, use the full
argument list and explicitly supply the default arguments.

Conformance improvements in Visual Studio


2019 version 16.7

is trivially copyable definition


C++20 changed the definition of is trivially copyable. When a class has a non-static data
member with volatile qualified-type, it no longer implies that any compiler-generated
copy or move constructor, or copy or move assignment operator, is non-trivial. The C++
Standard committee applied this change retroactively as a Defect Report. In MSVC, the
compiler behavior doesn't change in different language modes, such as /std:c++14 or
/std:c++latest .

Here's an example of the new behavior:

C++

#include <type_traits>

struct S
{
volatile int m;
};
static_assert(std::is_trivially_copyable_v<S>, "Meow!");

This code doesn't compile in versions of MSVC before Visual Studio 2019 version 16.7.
There's an off-by-default compiler warning that you can use to detect this change. If you
compile the code above by using cl /W4 /w45220 , you'll see the following warning:

Output

warning C5220: `'S::m': a non-static data member with a volatile qualified


type no longer implies that compiler generated copy/move constructors and
copy/move assignment operators are non trivial`

Pointer-to-member and string literal conversions to bool


are narrowing
The C++ Standard committee recently adopted Defect Report P1957R2 , which
considers T* to bool as a narrowing conversion. MSVC fixed a bug in its
implementation, which would previously diagnose T* to bool as narrowing, but didn't
diagnose the conversion of a string literal to bool or a pointer-to-member to bool .

The following program is ill-formed in Visual Studio 2019 version 16.7:

C++

struct X { bool b; };
void f(X);

int main() {
f(X { "whoops?" }); // error: conversion from 'const char [8]' to 'bool'
requires a narrowing conversion

int (X::* p) = nullptr;


f(X { p }); // error: conversion from 'int X::*' to 'bool' requires a
narrowing conversion
}

To correct this code, either add explicit comparisons to nullptr , or avoid contexts where
narrowing conversions are ill-formed:

C++

struct X { bool b; };
void f(X);
int main() {
f(X { "whoops?" != nullptr }); // Absurd, but OK

int (X::* p) = nullptr;


f(X { p != nullptr }); // OK
}

nullptr_t is only convertible to bool as a direct-


initialization
In C++11, nullptr is only convertible to bool as a direct-conversion; for example, when
you initialize a bool by using a braced initializer-list. This restriction was never enforced
by MSVC. MSVC now implements the rule under /permissive-. Implicit conversions are
now diagnosed as ill-formed. A contextual conversion to bool is still allowed, because
the direct-initialization bool b(nullptr) is valid.

In most cases, the error can be fixed by replacing nullptr with false , as shown in this
example:

C++

struct S { bool b; };
void g(bool);
bool h() { return nullptr; } // error, should be 'return false;'

int main() {
bool b1 = nullptr; // error: cannot convert from 'nullptr' to 'bool'
S s { nullptr }; // error: cannot convert from 'nullptr' to 'bool'
g(nullptr); // error: cannot convert argument 1 from 'nullptr' to 'bool'

bool b2 { nullptr }; // OK: Direct-initialization


if (!nullptr) {} // OK: Contextual conversion to bool
}

Conforming initialization behavior for array initializations


with missing initializers
Previously, MSVC had non-conforming behavior for array initializations that had missing
initializers. MSVC always called the default constructor for each array element that didn't
have an initializer. The standard behavior is to initialize each element with an empty
braced-initializer-list ( {} ). The initialization context for an empty braced-initializer-list is
copy-initialization, which doesn't allow calls to explicit constructors. There also may be
runtime differences, because use of {} to initialize may call a constructor that takes a
std::initializer_list , instead of the default constructor. The conforming behavior is

enabled under /permissive-.

Here's an example of the changed behavior:

C++

struct B {
explicit B() {}
};

void f() {
B b1[1]{}; // Error in /permissive-, because aggregate init calls
explicit ctor
B b2[1]; // OK: calls default ctor for each array element
}

Initialization of class members with overloaded names is


correctly sequenced
We identified a bug in class data members' internal representation when a type name is
also overloaded as a data member's name. This bug caused inconsistencies in aggregate
initialization and member initialization order. The generated initialization code is now
correct. However, this change can lead to errors or warnings in source that inadvertently
relied on the mis-ordered members, as in this example:

C++

// Compiling with /w15038 now gives:


// warning C5038: data member 'Outer::Inner' will be initialized after data
member 'Outer::v'
struct Outer {
Outer(int i, int j) : Inner{ i }, v{ j } {}

struct Inner { int x; };


int v;
Inner Inner; // 'Inner' is both a type name and data member name in the
same scope
};

In previous versions, the constructor would incorrectly initialize the data member Inner
before the data member v . (The C++ standard requires an initialization order that's the
same as the declaration order of the members). Now that the generated code follows
the standard, the member-init-list is out of order. The compiler generates a warning for
this example. To fix it, reorder the member-initializer-list to reflect the declaration order.
Overload resolution involving integral overloads and
long arguments

The C++ standard requires ranking a long to int conversion as a standard conversion.
Previous MSVC compilers incorrectly rank it as an integral promotion, which ranks
higher for overload resolution. This ranking can cause overload resolution to resolve
successfully when it should be considered ambiguous.

The compiler now considers the rank correctly in /permissive- mode. Invalid code gets
diagnosed properly, as in this example:

C++

void f(long long);


void f(int);

int main() {
long x {};
f(x); // error: 'f': ambiguous call to overloaded function
f(static_cast<int>(x)); // OK
}

You can fix this issue in several ways:

At the call site, change the type of the passed argument to int . You can either
change the variable type, or cast it.

If there are many call sites, you can add another overload that takes a long
argument. In this function, cast and forward the argument to the int overload.

Use of undefined variable with internal linkage


Versions of MSVC before Visual Studio 2019 version 16.7 accepted use of a variable
declared extern that had internal linkage and wasn't defined. Such variables can't be
defined in any other translation unit and can't form a valid program. The compiler now
diagnoses this case at compile time. The error is similar to the error for undefined static
functions.

C++

namespace {
extern int x; // Not a definition, but has internal linkage because of
the anonymous namespace
}
int main()
{
return x; // Use of 'x' that no other translation unit can possibly
define.
}

This program previously incorrectly compiled and linked, but will now emit error C7631.

Output

error C7631: 'anonymous-namespace::x': variable with internal linkage


declared but not defined

Such variables must be defined in the same translation unit they're used in. For example,
you can provide an explicit initializer or a separate definition.

Type completeness and derived-to-base pointer


conversions
In C++ standards before C++20, a conversion from a derived class to a base class didn't
require the derived class to be a complete class type. The C++ standard committee has
approved a retroactive Defect Report change that applies to all versions of the C++
language. This change aligns the conversion process with type traits, such as
std::is_base_of , which do require that the derived class is a complete class type.

Here's an example:

C++

template<typename A, typename B>


struct check_derived_from
{
static A a;
static constexpr B* p = &a;
};

struct W { };
struct X { };
struct Y { };

// With this change this code will fail as Z1 is not a complete class type
struct Z1 : X, check_derived_from<Z1, X>
{
};

// This code failed before and it will still fail after this change
struct Z2 : check_derived_from<Z2, Y>, Y
{
};

// With this change this code will fail as Z3 is not a complete class type
struct Z3 : W
{
check_derived_from<Z3, W> cdf;
};

This behavior change applies to all C++ language modes of MSVC, not just /std:c++20
or /std:c++latest .

Narrowing conversions are more consistently diagnosed


MSVC emits a warning for narrowing conversions in a braced-list initializer. Previously,
the compiler wouldn't diagnose narrowing conversions from larger enum underlying
types to narrower integral types. (The compiler incorrectly considered them an integral
promotion instead of a conversion). If the narrowing conversion is intentional, you can
avoid the warning by using a static_cast on the initializer argument. Or, choose a
larger destination integral type.

Here's an example of using an explicit static_cast to address the warning:

C++

enum E : long long { e1 };


struct S { int i; };

void f(E e) {
S s = { e }; // warning: conversion from 'E' to 'int' requires a
narrowing conversion
S s1 = { static_cast<int>(e) }; // Suppress warning with explicit
conversion
}

Conformance improvements in Visual Studio


2019 version 16.8

'Class rvalue used as lvalue' extension


MSVC has an extension that allows using a class rvalue as an lvalue. The extension
doesn't extend the lifetime of the class rvalue and can lead to undefined behavior at
runtime. We now enforce the standard rule and disallow this extension under
/permissive- . If you can't use /permissive- yet, you can use /we4238 to explicitly

disallow the extension. Here's an example:

C++

// Compiling with /permissive- now gives:


// error C2102: '&' requires l-value
struct S {};

S f();

void g()
{
auto p1 = &(f()); // The temporary returned by 'f' is destructed after
this statement. So 'p1' points to an invalid object.

const auto &r = f(); // This extends the lifetime of the temporary
returned by 'f'
auto p2 = &r; // 'p2' points to a valid object
}

'Explicit specialization in non-namespace scope'


extension
MSVC had an extension that allowed explicit specialization in non-namespace scope. It's
now part of the standard, after the resolution of CWG 727. However, there are behavior
differences. We've adjusted the behavior of our compiler to align with the standard.

C++

// Compiling with 'cl a.cpp b.cpp /permissive-' now gives:


// error LNK2005: "public: void __thiscall S::f<int>(int)" (??
$f@H@S@@QAEXH@Z) already defined in a.obj
// To fix the linker error,
// 1. Mark the explicit specialization with 'inline' explicitly. Or,
// 2. Move its definition to a source file.

// common.h
struct S {
template<typename T> void f(T);
template<> void f(int);
};

// This explicit specialization is implicitly inline in the default mode.


template<> void S::f(int) {}

// a.cpp
#include "common.h"
int main() {}

// b.cpp
#include "common.h"

Checking for abstract class types


The C++20 Standard changed the process compilers use to detect the use of an abstract
class type as a function parameter. Specifically, it's no longer a SFINAE error. Previously,
if the compiler detected that a specialization of a function template would have an
abstract class type instance as a function parameter, then that specialization would be
considered ill-formed. It wouldn't be added to the set of viable candidate functions. In
C++20, the check for a parameter of abstract class type doesn't happen until the
function is called. The effect is, code that used to compile won't cause an error. Here's
an example:

C++

class Node {
public:
int index() const;
};

class String : public Node {


public:
virtual int size() const = 0;
};

class Identifier : public Node {


public:
const String& string() const;
};

template<typename T>
int compare(T x, T y)
{
return x < y ? -1 : (x > y ? 1 : 0);
}

int compare(const Node& x, const Node& y)


{
return compare(x.index(), y.index());
}

int f(const Identifier& x, const String& y)


{
return compare(x.string(), y);
}
Previously, the call to compare would have attempted to specialize the function template
compare by using a String template argument for T . It would fail to generate a valid

specialization, because String is an abstract class. The only viable candidate would have
been compare(const Node&, const Node&) . However, under C++20 the check for the
abstract class type doesn't happen until the function is called. So, the specialization
compare(String, String) gets added to the set of viable candidates, and it's chosen as

the best candidate because the conversion from const String& to String is a better
conversion sequence than the conversion from const String& to const Node& .

Under C++20, one possible fix for this example is to use concepts; that is, change the
definition of compare to:

C++

template<typename T>
int compare(T x, T y) requires !std::is_abstract_v<T>
{
return x < y ? -1 : (x > y ? 1 : 0);
}

Or, if C++ concepts aren't available, you can fall back to SFINAE:

C++

template<typename T, std::enable_if_t<!std::is_abstract_v<T>, int> = 0>


int compare(T x, T y)
{
return x < y ? -1 : (x > y ? 1 : 0);
}

Support for P0960R3 - allow initializing aggregates from


a parenthesized list of values
C++20 P0960R3 adds support for initializing an aggregate using a parenthesized
initializer-list. For example, the following code is valid in C++20:

C++

struct S {
int i;
int j;
};

S s(1, 2);
Most of this feature is additive, that is, code now compiles that didn't compile before.
However, it does change the behavior of std::is_constructible . In C++17 mode this
static_assert fails, but in C++20 mode it succeeds:

C++

static_assert(std::is_constructible_v<S, int, int>, "Assertion failed!");

If you use this type-trait for control of overload resolution, it can lead to a change in
behavior between C++17 and C++20.

Overload resolution involving function templates


Previously, the compiler allowed some code to compile under /permissive- that
shouldn't compile. The effect was, the compiler called the wrong function leading to a
change in runtime behavior:

C++

int f(int);

namespace N
{
using ::f;
template<typename T>
T f(T);
}

template<typename T>
void g(T&& t)
{
}

void h()
{
using namespace N;
g(f);
}

The call to g uses an overload set that contains two functions, ::f and N::f . Since
N::f is a function template, the compiler should treat the function argument as a non-

deduced context. It means that, in this case, the call to g should fail, as the compiler can't
deduce a type for the template parameter T . Unfortunately, the compiler didn't discard
the fact that it had already decided that ::f was a good match for the function call.
Instead of emitting an error, the compiler would generate code to call g using ::f as
the argument.

Given that in many cases using ::f as the function argument is what the user expects,
we only emit an error if the code is compiled with /permissive- .

Migrating from /await to C++20 coroutines


Standard C++20 coroutines are now on by default under /std:c++20 and
/std:c++latest . They differ from the Coroutines TS and the support under the /await

option. Migrating from /await to standard coroutines may require some source
changes.

Non-standard keywords
The old await and yield keywords aren't supported in C++20 mode. Code must use
co_await and co_yield instead. Standard mode also doesn't allow the use of return in

a coroutine. Every return in a coroutine must use co_return .

C++

// /await
task f_legacy() {
...
await g();
return n;
}
// /std:c++latest
task f() {
...
co_await g();
co_return n;
}

Types of initial_suspend/final_suspend

Under /await , the promise initial and suspend functions may be declared as returning
bool . This behavior isn't standard. In C++20, these functions must return an awaitable

class type, often one of the trivial awaitable types: std::suspend_always if the function
previously returned true , or std::suspend_never if it returned false .

C++
// /await
struct promise_type_legacy {
bool initial_suspend() noexcept { return false; }
bool final_suspend() noexcept { return true; }
...
};

// /std:c++latest
struct promise_type {
auto initial_suspend() noexcept { return std::suspend_never{}; }
auto final_suspend() noexcept { return std::suspend_always{}; }
...
};

Type of yield_value
In C++20, the promise yield_value function must return an awaitable type. In /await
mode, the yield_value function was permitted to return void , and would always
suspend. Such functions can be replaced with a function that returns
std::suspend_always .

C++

// /await
struct promise_type_legacy {
...
void yield_value(int x) { next = x; };
};

// /std:c++latest
struct promise_type {
...
auto yield_value(int x) { next = x; return std::suspend_always{}; }
};

Exception handling function


/await supports a promise type with either no exception-handling function or an

exception handling function named set_exception that takes a std::exception_ptr . In


C++20, the promise type must have a function named unhandled_exception that takes
no arguments. The exception object can be obtained from std::current_exception if
needed.

C++
// /await
struct promise_type_legacy {
void set_exception(std::exception_ptr e) { saved_exception = e; }
...
};
// /std:c++latest
struct promise_type {
void unhandled_exception() { saved_exception = std::current_exception();
}
...
};

Deduced return types of coroutines not supported


C++20 doesn't support coroutines with a return type that includes a placeholder type
such as auto . Return types of coroutines must be explicitly declared. Under /await ,
these deduced types always involve an experimental type and require inclusion of a
header that defines the required type: One of std::experimental::task<T> ,
std::experimental::generator<T> , or std::experimental::async_stream<T> .

C++

// /await
auto my_generator() {
...
co_yield next;
};

// /std:c++latest
#include <experimental/generator>
std::experimental::generator<int> my_generator() {
...
co_yield next;
};

Return type of return_value

The return type of the promise return_value function must be void . In /await mode,
the return type can be anything, and is ignored. This diagnostic can help detect subtle
errors, such as when the author incorrectly assumes the return value of return_value is
returned to a caller.

C++
// /await
struct promise_type_legacy {
...
int return_value(int x) { return x; } // incorrect, the return value of
this function is unused and the value is lost.
};

// /std:c++latest
struct promise_type {
...
void return_value(int x) { value = x; }; // save return value
};

Return object conversion behavior


If the declared return type of a coroutine doesn't match the return type of the promise
get_return_object function, the object returned from get_return_object gets converted
to the return type of the coroutine. Under /await , this conversion is done early, before
the coroutine body has a chance to execute. In /std:c++20 or /std:c++latest , this
conversion is done when the value is returned to the caller. It allows coroutines that
don't suspend at the initial suspend point to make use of the object returned by
get_return_object within the coroutine body.

Coroutine promise parameters

In C++20, the compiler attempts to pass the coroutine parameters (if any) to a
constructor of the promise type. If it fails, it retries with a default constructor. In /await
mode, only the default constructor was used. This change can lead to a difference in
behavior if the promise has multiple constructors. Or, if there's a conversion from a
coroutine parameter to the promise type.

C++

struct coro {
struct promise_type {
promise_type() { ... }
promise_type(int x) { ... }
...
};
};

coro f1(int x);

// Under /await the promise gets constructed using the default constructor.
// Under /std:c++latest the promise gets constructed using the 1-argument
constructor.
f1(0);

struct Object {
template <typename T> operator T() { ... } // Converts to anything!
};

coro f2(Object o);

// Under /await the promise gets constructed using the default constructor
// Under /std:c++latest the promise gets copy- or move-constructed from the
result of
// Object::operator coro::promise_type().
f2(Object{});

/permissive- and C++20 Modules are on by default


under /std:c++20
C++20 Modules support is on by default under /std:c++20 and /std:c++latest . For
more information about this change, and the scenarios where module and import are
conditionally treated as keywords, see Standard C++20 Modules support with MSVC in
Visual Studio 2019 version 16.8 .

As a prerequisite for Modules support, permissive- is now enabled when /std:c++20 or


/std:c++latest is specified. For more information, see /permissive-.

For code that previously compiled under /std:c++latest and requires non-conforming
compiler behaviors, /permissive may be specified to turn off strict conformance mode
in the compiler. The compiler option must appear after /std:c++latest in the
command-line argument list. However, /permissive results in an error if Modules usage
is detected:

error C1214: Modules conflict with non-standard behavior requested via 'option'

The most common values for option are:

ノ Expand table

Option Description

/Zc:twoPhase- Two-phase name lookup is required for C++20 Modules and implied by
/permissive- .

/Zc:hiddenFriend- Standard hidden friend name lookup rules are required for C++20 Modules
and implied by /permissive- .
Option Description

/Zc:lambda- Standard lambda processing is required for C++20 Modules and is implied
by /std:c++20 mode or later.

/Zc:preprocessor- The conforming preprocessor is required for C++20 header unit usage and
creation only. Named Modules don't require this option.

The /experimental:module option is still required to use the std.* Modules that ship
with Visual Studio, because they're not standardized yet.

The /experimental:module option also implies /Zc:twoPhase , /Zc:lambda , and


/Zc:hiddenFriend . Previously, code compiled with Modules could sometimes be

compiled with /Zc:twoPhase- if the Module was only consumed. This behavior is no
longer supported.

Conformance improvements in Visual Studio


2019 version 16.9

Copy-initialization of temporary in reference direct-


initialization
Core Working Group issue CWG 2267 dealt with an inconsistency between a
parenthesized initializer list and a braced initializer list. The resolution harmonizes the
two forms.

Visual Studio 2019 version 16.9 implements the changed behavior in all /std compiler
modes. However, because it's potentially a source breaking change, it's only supported
if the code is compiled by using /permissive- .

This sample demonstrates the change in behavior:

C++

struct A { };

struct B {
explicit B(const A&);
};

void f()
{
A a;
const B& b1(a); // Always an error
const B& b2{ a }; // Allowed before resolution to CWG 2267 was
adopted: now an error
}

Destructor characteristics and potentially constructed


subobjects
Core Working Group issue CWG 2336 covers an omission about implicit exception
specifications of destructors in classes that have virtual base classes. The omission
meant a destructor in a derived class could have a weaker exception specification than a
base class, if that base was abstract and had a virtual base.

Visual Studio 2019 version 16.9 implements the changed behavior in all /std compiler
modes.

This sample shows how the interpretation changed:

C++

class V {
public:
virtual ~V() noexcept(false);
};

class B : virtual V {
virtual void foo () = 0;
// BEFORE: implicitly defined virtual ~B() noexcept(true);
// AFTER: implicitly defined virtual ~B() noexcept(false);
};

class D : B {
virtual void foo ();
// implicitly defined virtual ~D () noexcept(false);
};

Before this change, the implicitly defined destructor for B was noexcept , because only
potentially constructed subobjects get considered. And, base class V isn't a potentially
constructed subobject, because it's a virtual base and B is abstract. However, base
class V is a potentially constructed subobject of class D , and so D::~D is determined to
be noexcept(false) , leading to a derived class with a weaker exception specification
than its base. This interpretation is unsafe. It can lead to incorrect runtime behavior if an
exception gets thrown from a destructor of a class derived from B.

With this change, a destructor is also potentially throwing if it has a virtual destructor
and any virtual base class has a potentially throwing destructor.
Similar types and reference binding
Core Working Group issue CWG 2352 deals with an inconsistency between the
reference binding rules and changes to type similarity. The inconsistency was introduced
in earlier Defect Reports (such as CWG 330 ). This affected Visual Studio 2019 versions
16.0 through 16.8.

With this change, starting in Visual Studio 2019 version 16.9, code that previously bound
a reference to a temporary in Visual Studio 2019 version 16.0 through 16.8 may now
bind directly when the types involved differ only by cv-qualifiers.

Visual Studio 2019 version 16.9 implements the changed behavior in all /std compiler
modes. It's potentially a source breaking change.

See References to types with mismatched cv-qualifiers for a related change.

This sample shows the changed behavior:

C++

int *ptr;
const int *const &f() {
return ptr; // Now returns a reference to 'ptr' directly.
// Previously returned a reference to a temporary and emitted C4172
}

The update may change program behavior that relied on an introduced temporary:

C++

int func() {
int i1 = 13;
int i2 = 23;

int* iptr = &i1;


int const * const& iptrcref = iptr;

// iptrcref is a reference to a pointer to i1 with value 13.


if (*iptrcref != 13)
{
return 1;
}

// Now change what iptr points to.

// Prior to CWG 2352 iptrcref should be bound to a temporary and still


points to the value 13.
// After CWG 2352 it is bound directly to iptr and now points to the
value 23.
iptr = &i2;
if (*iptrcref != 23)
{
return 1;
}

return 0;
}

/Zc:twoPhase and /Zc:twoPhase- option behavior change

Normally, the MSVC compiler options work on the principle that the last one seen wins.
Unfortunately, it wasn't the case with the /Zc:twoPhase and /Zc:twoPhase- options.
These options were "sticky," so later options couldn't override them. For example:

cl /Zc:twoPhase /permissive a.cpp

In this case, the first /Zc:twoPhase option enables strict two-phase name lookup. The
second option is meant to disable the strict conformance mode (it's the opposite of
/permissive- ), but it didn't disable /Zc:twoPhase .

Visual Studio 2019 version 16.9 changes this behavior in all /std compiler modes.
/Zc:twoPhase and /Zc:twoPhase- are no longer "sticky," and later options can override
them.

Explicit noexcept-specifiers on destructor templates


The compiler previously accepted a destructor template declared with a non-throwing
exception specification but defined without an explicit noexcept-specifier. The implicit
exception specification of a destructor depends on properties of the class - properties
that may not be known at the point of definition of a template. The C++ Standard also
requires this behavior: If a destructor is declared without a noexcept-specifier, then it
has an implicit exception specification, and no other declaration of the function may
have a noexcept-specifier.

Visual Studio 2019 version 16.9 changes to conforming behavior in all /std compiler
modes.

This sample shows the change in compiler behavior:

C++

template <typename T>


class B {
virtual ~B() noexcept; // or throw()
};

template <typename T>


B<T>::~B() { /* ... */ } // Before: no diagnostic.
// Now diagnoses a definition mismatch. To fix, define the implementation by
// using the same noexcept-specifier. For example,
// B<T>::~B() noexcept { /* ... */ }

Rewritten expressions in C++20


Since Visual Studio 2019 version 16.2, under /std:c++latest , the compiler has accepted
code like this example:

C++

#include <compare>

struct S {
auto operator<=>(const S&) const = default;
operator bool() const;
};

bool f(S a, S b) {
return a < b;
}

However, the compiler wouldn't invoke the comparison function the author might
expect. The code above should have rewritten a < b as (a <=> b) < 0 . Instead, the
compiler used the operator bool() user-defined conversion function and compared
bool(a) < bool(b) . In Visual Studio 2019 version 16.9 and later, the compiler rewrites

the expression using the expected spaceship operator expression.

Source breaking change


Properly applying conversions to rewritten expressions has another effect: The compiler
also correctly diagnoses ambiguities from attempts to rewrite the expression. Consider
this example:

C++

struct Base {
bool operator==(const Base&) const;
};

struct Derived : Base {


Derived();
Derived(const Base&);
bool operator==(const Derived& rhs) const;
};

bool b = Base{} == Derived{};

In C++17, this code would be accepted because of the derived-to-base conversion of


Derived on the right-hand side of the expression. In C++20, the synthesized expression

candidate is also added: Derived{} == Base{} . Because of the rules in the standard
about which function wins based on conversions, it turns out that the choice between
Base::operator== and Derived::operator== is undecidable. Because the conversion

sequences in the two expressions are no better or worse than each other, the example
code results in an ambiguity.

To resolve the ambiguity, add a new candidate that won't be subject to the two
conversion sequences:

C++

bool operator==(const Derived&, const Base&);

Runtime breaking change

Because of the operator rewriting rules in C++20, it's possible for overload resolution to
find a new candidate that it wouldn't otherwise find in a lower language mode. And, the
new candidate may be a better match than the older candidate. Consider this example:

C++

struct iterator;
struct const_iterator {
const_iterator(const iterator&);
bool operator==(const const_iterator &ci) const;
};

struct iterator {
bool operator==(const const_iterator &ci) const { return ci == *this; }
};

In C++17, the only candidate for ci == *this is const_iterator::operator== . It's a


match because *this goes through a derived-to-base conversion to const_iterator . In
C++20, another rewritten candidate gets added: *this == ci , which invokes
iterator::operator== . This candidate requires no conversions, so it's a better match
than const_iterator::operator== . The problem with the new candidate is that it's the
function currently being defined, so the new semantics of the function causes an
infinitely recursive definition of iterator::operator== .

To help in code like the example, the compiler implements a new warning:

Windows Command Prompt

$ cl /std:c++latest /c t.cpp
t.cpp
t.cpp(8): warning C5232: in C++20 this comparison calls 'bool
iterator::operator ==(const const_iterator &) const' recursively

To fix the code, be explicit about which conversion to use:

C++

struct iterator {
bool operator==(const const_iterator &ci) const { return ci ==
static_cast<const const_iterator&>(*this); }
};

Conformance improvements in Visual Studio


2019 version 16.10

Wrong overload chosen for copy initialization of class


Given this sample code:

C++

struct A { template <typename T> A(T&&); };


struct B { operator A(); };
struct C : public B{};
void f(A);
f(C{});

Earlier versions of the compiler would incorrectly convert the argument of f from type
C to an A by using the templated converting constructor of A . Standard C++ requires
use of the conversion operator B::operator A instead. In Visual Studio 2019 version
16.10 and later, the overload resolution behavior is changed to use the correct overload.

This change can also correct the chosen overload in some other situations:
C++

struct Base
{
operator char *();
};

struct Derived : public Base


{
operator bool() const;
};

void f(Derived &d)


{
// Implicit conversion to bool previously used Derived::operator bool(),
now uses Base::operator char*.
// The Base function is preferred because operator bool() is declared
'const' and requires a qualification
// adjustment for the implicit object parameter, while the Base function
does not.
if (d)
{
// ...
}
}

Incorrect parsing of floating-point literals


In Visual Studio 2019 version 16.10 and later, floating-point literals are parsed based on
their actual type. Earlier versions of the compiler always parsed a floating-point literal as
if it had type double and then converted the result to the actual type. This behavior
could lead to incorrect rounding and rejection of valid values:

C++

// The binary representation is '0x15AE43FE' in VS2019 16.9


// The binary representation is '0x15AE43FD' in VS2019 16.10
// You can use 'static_cast<float>(7.038531E-26)' if you want the old
behavior.
float f = 7.038531E-26f;

Incorrect point of declaration


Earlier versions of the compiler couldn't compile self-referential code like this example:

C++
struct S {
S(int, const S*);

int value() const;


};

S s(4, &s);

The compiler wouldn't declare the variable s until it parsed the whole declaration,
including the constructor arguments. The lookup of the s in the constructor argument
list would fail. In Visual Studio 2019 version 16.10 and later, this example now compiles
correctly.

Unfortunately, this change can break existing code, as in this example:

C++

S s(1, nullptr); // outer s


// ...
{
S s(s.value(), nullptr); // inner s
}

In earlier versions of the compiler, when it looks up s in the constructor arguments for
the "inner" declaration of s , it finds the previous declaration ("outer" s ) and the code
compiles. Starting in version 16.10, the compiler emits warning C4700 instead. It's
because the compiler now declares the "inner" s before parsing the constructor
arguments. So, the s lookup finds the "inner" s , which hasn't been initialized yet.

Explicitly specialized member of a class template


Earlier versions of the compiler incorrectly marked an explicit specialization of a class
template member as inline if it was also defined in the primary template. This behavior
meant the compiler would sometimes reject conforming code. In Visual Studio 2019
version 16.10 and later, an explicit specialization is no longer implicitly marked as
inline in /permissive- mode. Consider this example:

Source file s.h :

C++

// s.h
template<typename T>
struct S {
int f() { return 1; }
};
template<> int S<int>::f() { return 2; }

Source file s.cpp :

C++

// s.cpp
#include "s.h"

Source file main.cpp :

C++

// main.cpp
#include "s.h"

int main()
{
}

To address the linker error in the above example, add inline explicitly to S<int>::f :

C++

template<> inline int S<int>::f() { return 2; }

Deduced return type name mangling


In Visual Studio 2019 version 16.10 and later, the compiler changed how it generates
mangled names for functions that have deduced return types. For example, consider
these functions:

C++

auto f() { return 0; }


auto g() { []{}; return 0; }

Earlier versions of the compiler would generate these names for the linker:

Console

f: ?f@@YAHXZ -> int __cdecl f(void)


g: ?g@@YA@XZ -> __cdecl g(void)

Surprisingly, the return type would be omitted from g because of other semantic
behavior caused by the local lambda in the function body. This inconsistency made it
difficult to implement exported functions that have a deduced return type: The module
interface requires information about how the body of a function was compiled. It needs
the information to produce a function on the import side that can properly link to the
definition.

The compiler now omits the return type of a deduced return type function. This behavior
is consistent with other major implementations. There's an exception for function
templates: this version of the compiler introduces a new mangled-name behavior for
function templates that have a deduced return type:

C++

template <typename T>


auto f(T) { return 1; }

template <typename T>


decltype(auto) g(T) { return 1.; }

int (*fp1)(int) = &f;


double (*fp2)(int) = &g;

The mangled names for auto and decltype(auto) now appear in the binary, not the
deduced return type:

Console

f: ??$f@H@@YA?A_PH@Z -> auto __cdecl f<int>(int)


g: ??$g@H@@YA?A_TH@Z -> decltype(auto) __cdecl g<int>(int)

Earlier versions of the compiler would include the deduced return type as part of the
signature. When the compiler included the return type in the mangled name, it could
cause linker issues. Some otherwise well-formed scenarios would become ambiguous to
the linker.

The new compiler behavior can produce a binary breaking change. Consider this
example:

Source file a.cpp :

C++
// a.cpp
auto f() { return 1; }

Source file main.cpp :

C++

// main.cpp
int f();
int main() { f(); }

In versions before version 16.10, the compiler produced a name for auto f() that
looked like int f() , even though they're semantically distinct functions. That means the
example would compile. To fix the issue, don't rely on auto in the original definition of
f . Instead, write it as int f() . Because functions that have deduced return types are

always compiled, the ABI implications are minimized.

Warning for ignored nodiscard attribute


Previous versions of the compiler would silently ignore certain uses of a nodiscard
attribute. They ignored the attribute if it was in a syntactic position that didn't apply to
the function or class being declared. For example:

C++

static [[nodiscard]] int f() { return 1; }

In Visual Studio 2019 version 16.10 and later, the compiler emits level 4 warning C5240
instead:

Console

a.cpp(1): warning C5240: 'nodiscard': attribute is ignored in this syntactic


position

To fix this issue, move the attribute to the correct syntactic position:

C++

[[nodiscard]] static int f() { return 1; }


Warning for include directives with system header-
names in module purview
In Visual Studio 2019 version 16.10 and later, the compiler emits a warning to prevent a
common module interface authoring mistake. If you include a standard library header
after an export module statement, the compiler emits warning C5244. Here's an
example:

C++

export module m;
#include <vector>

export
void f(std::vector<int>);

The developer probably didn't intend module m to own the contents of <vector> . The
compiler now emits a warning to help find and fix the issue:

Console

m.ixx(2): warning C5244: '#include <vector>' in the purview of module 'm'


appears erroneous. Consider moving that directive before the module
declaration, or replace the textual inclusion with an "import <vector>;".
m.ixx(1): note: see module 'm' declaration

To fix this issue, move #include <vector> before export module m; :

C++

#include <vector>
export module m;

export
void f(std::vector<int>);

Warning for unused internal linkage functions


In Visual Studio 2019 version 16.10 and later, the compiler warns in more situations
where an unreferenced function with internal linkage has been removed. Earlier versions
of the compiler would emit warning C4505 for the following code:

C++
static void f() // warning C4505: 'f': unreferenced function with internal
linkage has been removed
{
}

The compiler now also warns about unreferenced auto functions and unreferenced
functions in anonymous namespaces. It emits an off-by-default warning C5245 for both
of the following functions:

C++

namespace
{
void f1() // warning C5245: '`anonymous-namespace'::f1': unreferenced
function with internal linkage has been removed
{
}
}

auto f2() // warning C5245: 'f2': unreferenced function with internal


linkage has been removed
{
return []{ return 13; };
}

Warning on brace elision


In Visual Studio 2019 version 16.10 and later, the compiler warns on initialization lists
that don't use braces for subobjects. The compiler emits off-by-default warning C5246.

Here's an example:

C++

struct S1 {
int i, j;
};

struct S2 {
S1 s1;
int k;
};

S2 s2{ 1, 2, 3 }; // warning C5246: 'S2::s1': the initialization of a


subobject should be wrapped in braces

To fix this issue, wrap the initialization of the subobject in braces:


C++

S2 s2{ { 1, 2 }, 3 };

Correctly detect if a const object isn't initialized


In Visual Studio 2019 version 16.10 and later, the compiler now emits error C2737 when
you attempt to define a const object that isn't fully initialized:

C++

struct S {
int i;
int j = 2;
};

const S s; // error C2737: 's': const object must be initialized

Earlier versions of the compiler allowed this code to compile, even though S::i isn't
initialized.

To fix this issue, initialize all members before you create a const instance of an object:

C++

struct S {
int i = 1;
int j = 2;
};

Conformance improvements in Visual Studio


2019 version 16.11

/std:c++20 compiler mode

In Visual Studio 2019 version 16.11 and later, the compiler now supports the /std:c++20
compiler mode. Previously, C++20 features were available only in /std:c++latest mode
in Visual Studio 2019. C++20 features that originally required /std:c++latest mode
now work in /std:c++20 mode or later in the latest versions of Visual Studio.

See also
Microsoft C/C++ language conformance

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


C++ Conformance improvements,
behavior changes, and bug fixes in
Visual Studio 2017
Article • 06/06/2022

Microsoft C/C++ in Visual Studio (MSVC) makes conformance improvements and bug
fixes in every release. This article lists the improvements by major release, then by
version. To jump directly to the changes for a specific version, use list below In this
article.

This document lists the changes in Visual Studio 2017. For a guide to the changes in
Visual Studio 2022, see C++ conformance improvements in Visual Studio 2022. For a
guide to the changes in Visual Studio 2019, see C++ conformance improvements in
Visual Studio 2019. For a complete list of previous conformance improvements, see
Visual C++ What's New 2003 through 2015.

Conformance improvements in Visual Studio


2017 RTW (version 15.0)
With support for generalized constexpr and non-static data member initialization
(NSDMI) for aggregates, the MSVC compiler in Visual Studio 2017 is now complete for
features added in the C++14 standard. However, the compiler still lacks a few features
from the C++11 and C++98 standards. See Microsoft C/C++ language conformance for
the current state of the compiler.

C++11: Expression SFINAE support in more libraries


The compiler continues to improve its support for expression SFINAE. It's required for
template argument deduction and substitution where decltype and constexpr
expressions may appear as template parameters. For more information, see Expression
SFINAE improvements in Visual Studio 2017 RC .

C++14: NSDMI for aggregates


An aggregate is an array or a class that has: no user-provided constructor, no non-static
data members that are private or protected, no base classes, and no virtual functions.
Beginning in C++14, aggregates may contain member initializers. For more information,
see Member initializers and aggregates .

C++14: Extended constexpr


Expressions declared as constexpr are now allowed to contain certain kinds of
declarations, if and switch statements, loop statements, and mutation of objects whose
lifetime began within the constexpr expression evaluation. There's no longer a
requirement that a constexpr non-static member function must be implicitly const . For
more information, see Relaxing constraints on constexpr functions .

C++17: Terse static_assert


the message parameter for static_assert is optional. For more information, see N3928:
Extending static_assert, v2 .

C++17: [[fallthrough]] attribute


In /std:c++17 mode and later, the [[fallthrough]] attribute can be used in the context
of switch statements as a hint to the compiler that the fall-through behavior is intended.
This attribute prevents the compiler from issuing warnings in such cases. For more
information, see P0188R0 - Wording for [[fallthrough]] attribute .

Generalized range-based for loops


Range-based for loops no longer require that begin() and end() return objects of the
same type. This change enables end() to return a sentinel as used by ranges in range-v3
and the completed-but-not-quite-published Ranges Technical Specification. For more
information, see P0184R0 - Generalizing the Range-Based for Loop .

Copy-list-initialization
Visual Studio 2017 correctly raises compiler errors related to object creation using
initializer lists. These errors weren't caught in Visual Studio 2015, and could lead to
crashes or undefined runtime behavior. As per N4594 13.3.1.7p1 , in copy-list-
initialization , the compiler is required to consider an explicit constructor for overload

resolution. However, it must raise an error if that particular overload gets chosen.

The following two examples compile in Visual Studio 2015 but not in Visual Studio 2017.
C++

struct A
{
explicit A(int) {}
A(double) {}
};

int main()
{
A a1 = { 1 }; // error C3445: copy-list-initialization of 'A' cannot use
an explicit constructor
const A& a2 = { 1 }; // error C2440: 'initializing': cannot convert from
'int' to 'const A &'

To correct the error, use direct initialization:

C++

A a1{ 1 };
const A& a2{ 1 };

In Visual Studio 2015, the compiler erroneously treated copy-list-initialization in the


same way as regular copy-initialization: it considered only converting constructors for
overload resolution. In the following example, Visual Studio 2015 chooses MyInt(23) .
Visual Studio 2017 correctly raises the error.

C++

// From http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1228
struct MyStore {
explicit MyStore(int initialCapacity);
};

struct MyInt {
MyInt(int i);
};

struct Printer {
void operator()(MyStore const& s);
void operator()(MyInt const& i);
};

void f() {
Printer p;
p({ 23 }); // C3066: there are multiple ways that an object
// of this type can be called with these arguments
}

This example is similar to the previous one but raises a different error. It succeeds in
Visual Studio 2015 and fails in Visual Studio 2017 with C2668.

C++

struct A {
explicit A(int) {}
};

struct B {
B(int) {}
};

void f(const A&) {}


void f(const B&) {}

int main()
{
f({ 1 }); // error C2668: 'f': ambiguous call to overloaded function
}

Deprecated typedefs
Visual Studio 2017 now issues the correct warning for deprecated typedefs declared in a
class or struct. The following example compiles without warnings in Visual Studio 2015.
It produces C4996 in Visual Studio 2017.

C++

struct A
{
// also for __declspec(deprecated)
[[deprecated]] typedef int inttype;
};

int main()
{
A::inttype a = 0; // C4996 'A::inttype': was declared deprecated
}

constexpr
Visual Studio 2017 correctly raises an error when the left-hand operand of a
conditionally evaluating operation isn't valid in a constexpr context. The following code
compiles in Visual Studio 2015, but not in Visual Studio 2017, where it raises C3615:

C++

template<int N>
struct array
{
int size() const { return N; }
};

constexpr bool f(const array<1> &arr)


{
return arr.size() == 10 || arr.size() == 11; // C3615 constexpr function
'f' cannot result in a constant expression
}

To correct the error, either declare the array::size() function as constexpr or remove
the constexpr qualifier from f .

Class types passed to variadic functions


In Visual Studio 2017, classes or structs that are passed to a variadic function such as
printf must be trivially copyable. When such objects are passed, the compiler simply

makes a bitwise copy and doesn't call the constructor or destructor.

C++

#include <atomic>
#include <memory>
#include <stdio.h>

int main()
{
std::atomic<int> i(0);
printf("%i\n", i); // error C4839: non-standard use of class
'std::atomic<int>'
// as an argument to a variadic function.
// note: the constructor and destructor will not be
called;
// a bitwise copy of the class will be passed as the
argument
// error C2280: 'std::atomic<int>::atomic(const
std::atomic<int> &)':
// attempting to reference a deleted function

struct S {
S(int i) : i(i) {}
S(const S& other) : i(other.i) {}
operator int() { return i; }
private:
int i;
} s(0);
printf("%i\n", s); // warning C4840 : non-portable use of class
'main::S'
// as an argument to a variadic function
}

To correct the error, you can call a member function that returns a trivially copyable
type,

C++

std::atomic<int> i(0);
printf("%i\n", i.load());

or else use a static cast to convert the object before passing it:

C++

struct S {/* as before */} s(0);


printf("%i\n", static_cast<int>(s))

For strings built and managed using CString , the provided operator LPCTSTR() should
be used to cast a CString object to the C pointer expected by the format string.

C++

CString str1;
CString str2 = _T("hello!");
str1.Format(_T("%s"), static_cast<LPCTSTR>(str2));

Cv-qualifiers in class construction


In Visual Studio 2015, the compiler sometimes incorrectly ignores the cv-qualifier when
generating a class object via a constructor call. This issue can potentially cause a crash
or unexpected runtime behavior. The following example compiles in Visual Studio 2015
but raises a compiler error in Visual Studio 2017:

C++

struct S
{
S(int);
operator int();
};

int i = (const S)0; // error C2440

To correct the error, declare operator int() as const .

Access checking on qualified names in templates


Previous versions of the compiler didn't check access to qualified names in some
template contexts. This issue can interfere with expected SFINAE behavior, where the
substitution is expected to fail because of the inaccessibility of a name. It could have
potentially caused a crash or unexpected behavior at runtime, because the compiler
incorrectly called the wrong overload of the operator. In Visual Studio 2017, a compiler
error is raised. The specific error might vary, but a typical error is C2672, "no matching
overloaded function found." The following code compiles in Visual Studio 2015 but
raises an error in Visual Studio 2017:

C++

#include <type_traits>

template <class T> class S {


typedef typename T type;
};

template <class T, std::enable_if<std::is_integral<typename


S<T>::type>::value, T> * = 0>
bool f(T x);

int main()
{
f(10); // C2672: No matching overloaded function found.
}

Missing template argument lists


In Visual Studio 2015 and earlier, the compiler didn't diagnose all missing template
argument lists. It wouldn't note when the missing template appeared in a template
parameter list: for example, when part of a default template argument or a non-type
template parameter was missing. This issue can result in unpredictable behavior,
including compiler crashes or unexpected runtime behavior. The following code
compiles in Visual Studio 2015, but produces an error in Visual Studio 2017.
C++

template <class T> class ListNode;


template <class T> using ListNodeMember = ListNode<T> T::*;
template <class T, ListNodeMember M> class ListHead; // C2955:
'ListNodeMember': use of alias
// template requires
template argument list

// correct: template <class T, ListNodeMember<T> M> class ListHead;

Expression-SFINAE
To support expression-SFINAE, the compiler now parses decltype arguments when the
templates are declared rather than instantiated. So, if a non-dependent specialization is
found in the decltype argument, it's not deferred until instantiation-time. It's processed
immediately, and any resulting errors are diagnosed at that time.

The following example shows such a compiler error that is raised at the point of
declaration:

C++

#include <utility>
template <class T, class ReturnT, class... ArgsT>
class IsCallable
{
public:
struct BadType {};

template <class U>


static decltype(std::declval<T>()(std::declval<ArgsT>()...)) Test(int);
//C2064. Should be declval<U>

template <class U>


static BadType Test(...);

static constexpr bool value = std::is_convertible<decltype(Test<T>(0)),


ReturnT>::value;
};

constexpr bool test1 = IsCallable<int(), int>::value;


static_assert(test1, "PASS1");
constexpr bool test2 = !IsCallable<int*, int>::value;
static_assert(test2, "PASS2");

Classes declared in anonymous namespaces


According to the C++ standard, a class declared inside an anonymous namespace has
internal linkage, and that means it can't be exported. In Visual Studio 2015 and earlier,
this rule wasn't enforced. In Visual Studio 2017, the rule is partially enforced. In Visual
Studio 2017 the following example raises error C2201:

C++

struct __declspec(dllexport) S1 { virtual void f() {} };


// C2201 const anonymous namespace::S1::vftable: must have external
linkage
// in order to be exported/imported.

Default initializers for value class members (C++/CLI)


In Visual Studio 2015 and earlier, the compiler permitted (but ignored) a default
member initializer for a member of a value class. Default initialization of a value class
always zero-initializes the members. A default constructor isn't permitted. In Visual
Studio 2017, default member initializers raise a compiler error, as shown in this example:

C++

value struct V
{
int i = 0; // error C3446: 'V::i': a default member initializer
// isn't allowed for a member of a value class
};

Default indexers (C++/CLI)


In Visual Studio 2015 and earlier, the compiler in some cases misidentified a default
property as a default indexer. It was possible to work around the issue by using the
identifier default to access the property. The workaround itself became problematic
after default was introduced as a keyword in C++11. In Visual Studio 2017, the bugs
that required the workaround were fixed. The compiler now raises an error when
default is used to access the default property for a class.

C++

//class1.cs

using System.Reflection;
using System.Runtime.InteropServices;

namespace ClassLibrary1
{
[DefaultMember("Value")]
public class Class1
{
public int Value
{
// using attribute on the return type triggers the compiler bug
[return: MarshalAs(UnmanagedType.I4)]
get;
}
}
[DefaultMember("Value")]
public class Class2
{
public int Value
{
get;
}
}
}

// code.cpp
#using "class1.dll"

void f(ClassLibrary1::Class1 ^r1, ClassLibrary1::Class2 ^r2)


{
r1->Value; // error
r1->default;
r2->Value;
r2->default; // error
}

In Visual Studio 2017, you can access both Value properties by their name:

C++

#using "class1.dll"

void f(ClassLibrary1::Class1 ^r1, ClassLibrary1::Class2 ^r2)


{
r1->Value;
r2->Value;
}

Conformance improvements in 15.3

constexpr lambdas
Lambda expressions may now be used in constant expressions. For more information,
see constexpr lambda expressions in C++.

if constexpr in function templates

A function template may contain if constexpr statements to enable compile-time


branching. For more information, see if constexpr statements.

Selection statements with initializers


An if statement may include an initializer that introduces a variable at block scope
within the statement itself. For more information, see if statements with initializer.

[[maybe_unused]] and [[nodiscard]] attributes

New attribute [[maybe_unused]] silences warnings when an entity isn't used. The
[[nodiscard]] attribute creates a warning if the return value of a function call is

discarded. For more information, see Attributes in C++.

Using attribute namespaces without repetition


New syntax to enable only a single namespace identifier in an attribute list. For more
information, see Attributes in C++.

Structured bindings
It's now possible in a single declaration to store a value with individual names for its
components, when the value is an array, a std::tuple or std::pair , or has all public
non-static data members. For more information, see P0144R0 - Structured Bindings
and Returning multiple values from a function.

Construction rules for enum class values


There's now an implicit conversion for scoped enumerations that's non-narrowing. It
converts from a scoped enumeration's underlying type to the enumeration itself. The
conversion is available when its definition doesn't introduce an enumerator, and when
the source uses a list-initialization syntax. For more information, see P0138R2 -
Construction Rules for enum class Values and Enumerations.
Capturing *this by value
The *this object in a lambda expression may now be captured by value. This change
enables scenarios in which the lambda is invoked in parallel and asynchronous
operations, especially on newer machine architectures. For more information, see
P0018R3 - Lambda Capture of *this by Value as [=,*this] .

Removing operator++ for bool


operator++ is no longer supported on bool types. For more information, see P0002R1 -
Remove Deprecated operator++(bool) .

Removing deprecated register keyword


The register keyword, previously deprecated (and ignored by the compiler), is now
removed from the language. For more information, see P0001R1 - Remove Deprecated
Use of the register Keyword .

Calls to deleted member templates


In previous versions of Visual Studio, the compiler in some cases would fail to emit an
error for ill-formed calls to a deleted member template. These calls would potentially
cause crashes at runtime. The following code now produces C2280:

C++

template<typename T>
struct S {
template<typename U> static int f() = delete;
};

void g()
{
decltype(S<int>::f<int>()) i; // this should fail with
// C2280: 'int S<int>::f<int>(void)': attempting to reference a deleted
function
}

To fix the error, declare i as int .

Pre-condition checks for type traits


Visual Studio 2017 version 15.3 improves pre-condition checks for type-traits to more
strictly follow the standard. One such check is for assignable. The following code
produces C2139 in Visual Studio 2017 version 15.3:

C++

struct S;
enum E;

static_assert(!__is_assignable(S, S), "fail"); // C2139 in 15.3


static_assert(__is_convertible_to(E, E), "fail"); // C2139 in 15.3

New compiler warning and runtime checks on native-to-


managed marshaling
Calling from managed functions to native functions requires marshaling. The CLR does
the marshaling, but it doesn't understand C++ semantics. If you pass a native object by
value, CLR either calls the object's copy-constructor or uses BitBlt , which may cause
undefined behavior at runtime.

Now the compiler emits a warning if it finds this error at compile time: a native object
with deleted copy ctor gets passed between a native and managed boundary by value.
For those cases in which the compiler doesn't know at compile time, it injects a runtime
check so that the program calls std::terminate immediately when an ill-formed
marshaling occurs. In Visual Studio 2017 version 15.3, the following code produces
warning C4606:

C++

class A
{
public:
A() : p_(new int) {}
~A() { delete p_; }

A(A const &) = delete;


A(A &&rhs) {
p_ = rhs.p_;
}

private:
int *p_;
};

#pragma unmanaged

void f(A a)
{
}

#pragma managed

int main()
{
// This call from managed to native requires marshaling. The CLR doesn't
// understand C++ and uses BitBlt, which results in a double-free later.
f(A()); // C4606 'A': passing argument by value across native and
managed
// boundary requires valid copy constructor. Otherwise, the runtime
// behavior is undefined.`
}

To fix the error, remove the #pragma managed directive to mark the caller as native and
avoid marshaling.

Experimental API warning for WinRT


WinRT APIs that are released for experimentation and feedback are decorated with
Windows.Foundation.Metadata.ExperimentalAttribute . In Visual Studio 2017 version 15.3,

the compiler produces warning C4698 for this attribute. A few APIs in previous versions
of the Windows SDK have already been decorated with the attribute, and calls to these
APIs now trigger this compiler warning. Newer Windows SDKs have the attribute
removed from all shipped types. If you're using an older SDK, you'll need to suppress
these warnings for all calls to shipped types.

The following code produces warning C4698:

C++

Windows::Storage::IApplicationDataStatics2::GetForUserAsync(); // C4698
// 'Windows::Storage::IApplicationDataStatics2::GetForUserAsync' is for
// evaluation purposes only and is subject to change or removal in future
updates

To disable the warning, add a #pragma:

C++

#pragma warning(push)
#pragma warning(disable:4698)

Windows::Storage::IApplicationDataStatics2::GetForUserAsync();
#pragma warning(pop)

Out-of-line definition of a template member function


Visual Studio 2017 version 15.3 produces an error for an out-of-line definition of a
template member function that wasn't declared in the class. The following code now
produces error C2039:

C++

struct S {};

template <typename T>


void S::f(T t) {} // C2039: 'f': is not a member of 'S'

To fix the error, add a declaration to the class:

C++

struct S {
template <typename T>
void f(T t);
};
template <typename T>
void S::f(T t) {}

Attempting to take the address of this pointer


In C++, this is a prvalue of type pointer to X. You can't take the address of this or
bind it to an lvalue reference. In previous versions of Visual Studio, the compiler would
allow you to circumvent this restriction by use of a cast. In Visual Studio 2017 version
15.3, the compiler produces error C2664.

Conversion to an inaccessible base class


Visual Studio 2017 version 15.3 produces an error when you attempt to convert a type
to a base class that is inaccessible. The following code is ill-formed and can potentially
cause a crash at runtime. The compiler now produces C2243 when it sees code like this:

C++
#include <memory>

class B { };
class D : B { }; // C2243: 'type cast': conversion from 'D *' to 'B *'
exists, but is inaccessible

void f()
{
std::unique_ptr<B>(new D());
}

Default arguments aren't allowed on out of line


definitions of member functions
Default arguments aren't allowed on out-of-line definitions of member functions in
template classes. The compiler will issue a warning under /permissive , and a hard error
under /permissive-.

In previous versions of Visual Studio, the following ill-formed code could potentially
cause a runtime crash. Visual Studio 2017 version 15.3 produces warning C5037:

C++

template <typename T>


struct A {
T f(T t, bool b = false);
};

template <typename T>


T A<T>::f(T t, bool b = false) // C5037: 'A<T>::f': an out-of-line
definition of a member of a class template cannot have default arguments
{
// ...
}

To fix the error, remove the = false default argument.

Use of offsetof with compound member designator


In Visual Studio 2017 version 15.3, using offsetof(T, m) where m is a "compound
member designator" results in a warning when you compile with the /Wall option. The
following code is ill-formed and could potentially cause a crash at runtime. Visual Studio
2017 version 15.3 produces warning C4841:

C++
struct A {
int arr[10];
};

// warning C4841: non-standard extension used: compound member designator


used in offsetof
constexpr auto off = offsetof(A, arr[2]);

To fix the code, either disable the warning with a pragma or change the code to not use
offsetof :

C++

#pragma warning(push)
#pragma warning(disable: 4841)
constexpr auto off = offsetof(A, arr[2]);
#pragma warning(pop)

Using offsetof with static data member or member


function
In Visual Studio 2017 version 15.3, using offsetof(T, m) where m refers to a static data
member or a member function results in an error. The following code produces error
C4597:

C++

#include <cstddef>

struct A {
int ten() { return 10; }
static constexpr int two = 2;
};

constexpr auto off = offsetof(A, ten); // C4597: undefined behavior:


offsetof applied to member function 'A::ten'
constexpr auto off2 = offsetof(A, two); // C4597: undefined behavior:
offsetof applied to static data member 'A::two'

This code is ill-formed and could potentially cause a crash at runtime. To fix the error,
change the code to no longer invoke undefined behavior. It's non-portable code that's
disallowed by the C++ standard.

New warning on __declspec attributes


In Visual Studio 2017 version 15.3, the compiler no longer ignores attributes if
__declspec(...) is applied before extern "C" linkage specification. Previously, the

compiler would ignore the attribute, which could have runtime implications. When the
/Wall and /WX options are set, the following code produces warning C4768:

C++

__declspec(noinline) extern "C" HRESULT __stdcall // C4768: __declspec


attributes before linkage specification are ignored

To fix the warning, put extern "C" first:

C++

extern "C" __declspec(noinline) HRESULT __stdcall

This warning is off by default in Visual Studio 2017 version 15.3, and only impacts code
compiled with /Wall /WX . Starting in Visual Studio 2017 version 15.5, it's enabled by
default as a level 3 warning.

decltype and calls to deleted destructors

In previous versions of Visual Studio, the compiler didn't detect when a call to a deleted
destructor occurred in the context of the expression associated with decltype . In Visual
Studio 2017 version 15.3, the following code produces error C2280:

C++

template<typename T>
struct A
{
~A() = delete;
};

template<typename T>
auto f() -> A<T>;

template<typename T>
auto g(T) -> decltype((f<T>()));

void h()
{
g(42); // C2280: 'A<T>::~A(void)': attempting to reference a deleted
function
}
Uninitialized const variables
Visual Studio 2017 RTW release had a regression: the C++ compiler wouldn't issue a
diagnostic for an uninitialized const variable. This regression has been fixed in Visual
Studio 2017 version 15.3. The following code now produces warning C4132:

C++

const int Value; // C4132: 'Value': const object should be initialized

To fix the error, assign a value to Value .

Empty declarations
Visual Studio 2017 version 15.3 now warns on empty declarations for all types, not just
built-in types. The following code now produces a level 2 C4091 warning for all four
declarations:

C++

struct A {};
template <typename> struct B {};
enum C { c1, c2, c3 };

int; // warning C4091 : '' : ignored on left of 'int' when no variable is


declared
A; // warning C4091 : '' : ignored on left of 'main::A' when no
variable is declared
B<int>; // warning C4091 : '' : ignored on left of 'B<int>' when no variable
is declared
C; // warning C4091 : '' : ignored on left of 'C' when no variable is
declared

To remove the warnings, comment-out or remove the empty declarations. In cases


where the unnamed object is intended to have a side effect (such as RAII), it should be
given a name.

The warning is excluded under /Wv:18 and is on by default under warning level W2.

std::is_convertible for array types

Previous versions of the compiler gave incorrect results for std::is_convertible for array
types. This required library writers to special-case the Microsoft C++ compiler when
using the std::is_convertible<...> type trait. In the following example, the static
asserts pass in earlier versions of Visual Studio but fail in Visual Studio 2017 version 15.3:

C++

#include <type_traits>

using Array = char[1];

static_assert(std::is_convertible<Array, Array>::value);
static_assert(std::is_convertible<const Array, const Array>::value, "");
static_assert(std::is_convertible<Array&, Array>::value, "");
static_assert(std::is_convertible<Array, Array&>::value, "");

std::is_convertible<From, To> is calculated by checking to see if an imaginary function

definition is well formed:

C++

To test() { return std::declval<From>(); }

Private destructors and std::is_constructible


Previous versions of the compiler ignored whether a destructor was private when
deciding the result of std::is_constructible. It now considers them. In the following
example, the static asserts pass in earlier versions of Visual Studio but fail in Visual
Studio 2017 version 15.3:

C++

#include <type_traits>

class PrivateDtor {
PrivateDtor(int) { }
private:
~PrivateDtor() { }
};

// This assertion used to succeed. It now correctly fails.


static_assert(std::is_constructible<PrivateDtor, int>::value);

Private destructors cause a type to be non-constructible. std::is_constructible<T,


Args...> is calculated as if the following declaration were written:

C++
T obj(std::declval<Args>()...)

This call implies a destructor call.

C2668: Ambiguous overload resolution


Previous versions of the compiler sometimes failed to detect ambiguity when it found
multiple candidates via both using declarations and argument-dependent lookup. This
failure can lead to the wrong overload being chosen, and to unexpected runtime
behavior. In the following example, Visual Studio 2017 version 15.3 correctly raises
C2668:

C++

namespace N {
template<class T>
void f(T&, T&);

template<class T>
void f();
}

template<class T>
void f(T&, T&);

struct S {};
void f()
{
using N::f;

S s1, s2;
f(s1, s2); // C2668: 'f': ambiguous call to overloaded function
}

To fix the code, remove the using N::f statement if you intended to call ::f() .

C2660: local function declarations and argument-


dependent lookup
Local function declarations hide the function declaration in the enclosing scope and
disable argument-dependent lookup. Previous versions of the compiler always did
argument-dependent lookup in this case. It could potentially lead to unexpected
runtime behavior, if the compiler chose the wrong overload. Typically, the error is
because of an incorrect signature of the local function declaration. In the following
example, Visual Studio 2017 version 15.3 correctly raises C2660:

C++

struct S {};
void f(S, int);

void g()
{
void f(S); // C2660 'f': function does not take 2 arguments:
// or void f(S, int);
S s;
f(s, 0);
}

To fix the problem, either change the f(S) signature or remove it.

C5038: order of initialization in initializer lists


Class members get initialized in the order they're declared, not the order they appear in
initializer lists. Previous versions of the compiler didn't warn when the order of the
initializer list differed from the order of declaration. This issue could lead to undefined
runtime behavior if one member's initialization depended on another member in the list
already being initialized. In the following example, Visual Studio 2017 version 15.3 (with
/Wall ) raises warning C5038:

C++

struct A
{ // Initialized in reverse, y reused
A(int a) : y(a), x(y) {} // C5038: data member 'A::y' will be
initialized after data member 'A::x'
int x;
int y;
};

To fix the problem, arrange the initializer list to have the same order as the declarations.
A similar warning is raised when one or both initializers refer to base class members.

This warning is off-by-default, and only affects code compiled with /Wall .

Conformance improvements in 15.5


Features marked with [14] are available unconditionally even in /std:c++14 mode.
New compiler switch for extern constexpr
In earlier versions of Visual Studio, the compiler always gave a constexpr variable
internal linkage, even when the variable was marked extern . In Visual Studio 2017
version 15.5, a new compiler switch, /Zc:externConstexpr, enables correct and standards-
conforming behavior. For more information, see extern constexpr linkage.

Removing dynamic exception specifications


P0003R5 Dynamic exception specifications were deprecated in C++11. The feature is
removed from C++17, but the (still) deprecated throw() specification is kept strictly as
an alias for noexcept(true) . For more information, see Dynamic exception specification
removal and noexcept.

not_fn()

P0005R4 not_fn is a replacement of not1 and not2 .

Rewording enable_shared_from_this
P0033R1 enable_shared_from_this was added in C++11. The C++17 standard

updates the specification to better handle certain corner cases. [14]

Splicing maps and sets


P0083R3 This feature enables extraction of nodes from associative containers (that is,
map , set , unordered_map , unordered_set ) which can then be modified and inserted back

into the same container or a different container that uses the same node type. (A
common use case is to extract a node from a std::map , change the key, and reinsert.)

Deprecating vestigial library parts


P0174R2 Several features of the C++ standard library have been superseded by newer
features over the years, or else have been found not useful, or problematic. These
features are officially deprecated in C++17.

Removing allocator support in std::function


P0302R1 Prior to C++17, the class template std::function had several constructors
that took an allocator argument. However, the use of allocators in this context was
problematic, and the semantics were unclear. The problem contructors have been
removed.

Fixes for not_fn()


P0358R1 New wording for std::not_fn provides support of propagation of value
category when used in wrapper invocation.

shared_ptr<T[]> , shared_ptr<T[N]>

P0414R2 Merging shared_ptr changes from Library Fundamentals to C++17. [14]

Fixing shared_ptr for arrays


P0497R0 Fixes to shared_ptr support for arrays. [14]

Clarifying insert_return_type
P0508R0 The associative containers with unique keys, and the unordered containers
with unique keys have a member function insert that returns a nested type
insert_return_type . That return type is now defined as a specialization of a type that is

parameterized on the Iterator and NodeType of the container.

Inline variables for the standard library


For P0607R0 , several common variables declared in the standard library are now
declared inline.

Annex D features deprecated


Annex D of the C++ standard contains all the features that have been deprecated,
including shared_ptr::unique() , <codecvt> , and namespace std::tr1 . When the
/std:c++17 or later compiler option is set, almost all the standard library features in

Annex D are marked as deprecated. For more information, see Standard library features
in Annex D are marked as deprecated.

The std::tr2::sys namespace in <experimental/filesystem> now emits a deprecation


warning under /std:c++14 by default, and is now removed under /std:c++17 and later
by default.

Improved conformance in <iostream> by avoiding a non-standard extension (in-class


explicit specializations).

The standard library now uses variable templates internally.

The standard library was updated in response to C++17 compiler changes. Updates
include the addition of noexcept in the type system, and the removal of dynamic-
exception-specifications.

Partial ordering change


The compiler now correctly rejects the following code and gives the correct error
message:

C++

template<typename... T>
int f(T* ...)
{
return 1;
}

template<typename T>
int f(const T&)
{
return 2;
}

int main()
{
int i = 0;
f(&i); // C2668
}

Output

t161.cpp
t161.cpp(16): error C2668: 'f': ambiguous call to overloaded function
t161.cpp(8): note: could be 'int f<int*>(const T &)'
with
[
T=int*
]
t161.cpp(2): note: or 'int f<int>(int*)'
t161.cpp(16): note: while trying to match the argument list '(int*)'
The problem in the example above is that there are two differences in the types (const
vs. non-const and pack vs. non-pack). To eliminate the compiler error, remove one of
the differences. Then the compiler can unambiguously order the functions.

C++

template<typename... T>
int f(T* ...)
{
return 1;
}

template<typename T>
int f(T&)
{
return 2;
}

int main()
{
int i = 0;
f(&i);
}

Exception handlers
Handlers of reference to array or function type are never a match for any exception
object. The compiler now correctly honors this rule and raises a level 4 warning, C4843.
It also no longer matches a handler of char* or wchar_t* to a string literal when
/Zc:strictStrings is used.

C++

int main()
{
try {
throw "";
}
catch (int (&)[1]) {} // C4843 (This should always be dead code.)
catch (void (&)()) {} // C4843 (This should always be dead code.)
catch (char*) {} // This should not be a match under /Zc:strictStrings
}

Output

warning C4843: 'int (&)[1]': An exception handler of reference to array or


function type is unreachable, use 'int*' instead
warning C4843: 'void (__cdecl &)(void)': An exception handler of reference
to array or function type is unreachable, use 'void (__cdecl*)(void)'
instead

The following code avoids the error:

C++

catch (int (*)[1]) {}

std::tr1 namespace is deprecated

The non-standard std::tr1 namespace is now marked as deprecated in both C++14


and C++17 modes. In Visual Studio 2017 version 15.5, the following code raises C4996:

C++

#include <functional>
#include <iostream>
using namespace std;

int main() {
std::tr1::function<int (int, int)> f = std::plus<int>(); //C4996
cout << f(3, 5) << std::endl;
f = std::multiplies<int>();
cout << f(3, 5) << std::endl;
}

Output

warning C4996: 'std::tr1': warning STL4002: The non-standard std::tr1


namespace and TR1-only machinery are deprecated and will be REMOVED. You can
define _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING to acknowledge that you
have received this warning.

To fix the error, remove the reference to the tr1 namespace:

C++

#include <functional>
#include <iostream>
using namespace std;

int main() {
std::function<int (int, int)> f = std::plus<int>();
cout << f(3, 5) << std::endl;
f = std::multiplies<int>();
cout << f(3, 5) << std::endl;
}

Standard library features in Annex D are marked as


deprecated
When the /std:c++17 mode or later compiler switch is set, almost all standard library
features in Annex D are marked as deprecated.

In Visual Studio 2017 version 15.5, the following code raises C4996:

C++

#include <iterator>

class MyIter : public std::iterator<std::random_access_iterator_tag, int> {


public:
// ... other members ...
};

#include <type_traits>

static_assert(std::is_same<MyIter::pointer, int*>::value, "BOOM");

Output

warning C4996:
'std::iterator<std::random_access_iterator_tag,int,ptrdiff_t,_Ty*,_Ty
&>::pointer': warning STL4015: The std::iterator class template (used as a
base class to provide typedefs) is deprecated in C++17. (The <iterator>
header is NOT deprecated.) The C++ standard has never required user-defined
iterators to derive from std::iterator. To fix this warning, stop deriving
from std::iterator and start providing publicly accessible typedefs named
iterator_category, value_type, difference_type, pointer, and reference. Note
that value_type is required to be non-const, even for constant iterators.
You can define _SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING or
_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS to acknowledge that you have
received this warning.

To fix the error, follow the instructions in the warning text, as demonstrated in the
following code:

C++

#include <iterator>

class MyIter {
public:
typedef std::random_access_iterator_tag iterator_category;
typedef int value_type;
typedef ptrdiff_t difference_type;
typedef int* pointer;
typedef int& reference;

// ... other members ...


};

#include <type_traits>

static_assert(std::is_same<MyIter::pointer, int*>::value, "BOOM");

Unreferenced local variables


In Visual Studio 15.5, warning C4189 is emitted in more cases, as shown in the following
code:

C++

void f() {
char s[2] = {0}; // C4189. Either use the variable or remove it.
}

Output

warning C4189: 's': local variable is initialized but not referenced

To fix the error, remove the unused variable.

Single-line comments
In Visual Studio 2017 version 15.5, warnings C4001 and C4179 are no longer emitted by
the C compiler. Previously, they were only emitted under the /Za compiler switch. The
warnings are no longer needed because single-line comments have been part of the C
standard since C99.

C++

/* C only */
#pragma warning(disable:4001) // C4619
#pragma warning(disable:4179)
// single line comment
//* single line comment */
Output

warning C4619: #pragma warning: there is no warning number '4001'

When the code doesn't need to be backwards compatible, avoid the warning by
removing the C4001 and C4179 suppression. If the code does need to be backward
compatible, then suppress C4619 only.

/* C only */

#pragma warning(disable:4619)
#pragma warning(disable:4001)
#pragma warning(disable:4179)

// single line comment


/* single line comment */

__declspec attributes with extern "C" linkage

In earlier versions of Visual Studio, the compiler ignored __declspec(...) attributes


when __declspec(...) was applied before the extern "C" linkage specification. This
behavior caused code to be generated that user didn't intend, with possible runtime
implications. The C4768 warning was added in Visual Studio version 15.3, but was off by
default. In Visual Studio 2017 version 15.5, the warning is enabled by default.

C++

__declspec(noinline) extern "C" HRESULT __stdcall // C4768

Output

warning C4768: __declspec attributes before linkage specification are


ignored

To fix the error, place the linkage specification before the __declspec attribute:

C++

extern "C" __declspec(noinline) HRESULT __stdcall


This new warning C4768 is given on some Windows SDK headers that were shipped with
Visual Studio 2017 15.3 or older (for example: version 10.0.15063.0, also known as RS2
SDK). However, later versions of Windows SDK headers (specifically, ShlObj.h and
ShlObj_core.h) have been fixed so that they don't produce the warning. When you see
this warning coming from Windows SDK headers, you can take these actions:

1. Switch to the latest Windows SDK that came with Visual Studio 2017 version 15.5
release.

2. Turn off the warning around the #include of the Windows SDK header statement:

C++

#pragma warning (push)


#pragma warning(disable:4768)
#include <shlobj.h>
#pragma warning (pop)

extern constexpr linkage

In earlier versions of Visual Studio, the compiler always gave a constexpr variable
internal linkage even when the variable was marked extern . In Visual Studio 2017
version 15.5, a new compiler switch ( /Zc:externConstexpr ) enables correct, standards-
conforming behavior. Eventually this behavior will become the default.

C++

extern constexpr int x = 10;

Output

error LNK2005: "int const x" already defined

If a header file contains a variable declared extern constexpr , it needs to be marked


__declspec(selectany) to have its duplicate declarations combined correctly:

C++

extern constexpr __declspec(selectany) int x = 10;

typeid can't be used on incomplete class type


In earlier versions of Visual Studio, the compiler incorrectly allowed the following code,
resulting in potentially incorrect type information. In Visual Studio 2017 version 15.5, the
compiler correctly raises an error:

C++

#include <typeinfo>

struct S;

void f() { typeid(S); } //C2027 in 15.5

Output

error C2027: use of undefined type 'S'

std::is_convertible target type

std::is_convertible requires the target type to be a valid return type. In earlier versions

of Visual Studio, the compiler incorrectly allowed abstract types, which might lead to
incorrect overload resolution and unintended runtime behavior. The following code now
correctly raises C2338:

C++

#include <type_traits>

struct B { virtual ~B() = 0; };


struct D : public B { virtual ~D(); };

static_assert(std::is_convertible<D, B>::value, "fail"); // C2338 in 15.5

To avoid the error, when using is_convertible you should compare pointer types
because a non-pointer-type comparison might fail if one type is abstract:

C++

#include <type_traits>

struct B { virtual ~B() = 0; };


struct D : public B { virtual ~D(); };

static_assert(std::is_convertible<D *, B *>::value, "fail");


Dynamic exception specification removal and noexcept
In C++17, throw() is an alias for noexcept , throw(<type list>) and throw(...) are
removed, and certain types may include noexcept . This change can cause source
compatibility issues with code that conforms to C++14 or earlier. The
/Zc:noexceptTypes- switch can be used to revert to the C++14 version of noexcept

while using C++17 mode in general. It enables you to update your source code to
conform to C++17 without having to rewrite all your throw() code at the same time.

The compiler also now diagnoses more mismatched exception specifications in


declarations in C++17 mode or with /permissive- with the new warning C5043.

The following code generates C5043 and C5040 in Visual Studio 2017 version 15.5 when
the /std:c++17 switch is applied:

C++

void f() throw(); // equivalent to void f() noexcept;


void f() {} // warning C5043
void g() throw(); // warning C5040

struct A {
virtual void f() throw();
};

struct B : A {
virtual void f() { } // error C2694
};

To remove the errors while still using /std:c++17 , either add the /Zc:noexceptTypes-
switch to the command line, or else update your code to use noexcept , as shown in the
following example:

C++

void f() noexcept;


void f() noexcept { }
void g() noexcept(false);

struct A {
virtual void f() noexcept;
};

struct B : A {
virtual void f() noexcept { }
};
Inline variables
Static constexpr data members are now implicitly inline , which means that their
declaration within a class is now their definition. Using an out-of-line definition for a
static constexpr data member is redundant, and now deprecated. In Visual Studio

2017 version 15.5, when the /std:c++17 switch is applied the following code now
produces warning C5041:

C++

struct X {
static constexpr int size = 3;
};
const int X::size; // C5041: 'size': out-of-line definition for constexpr
static data member is not needed and is deprecated in C++17

extern "C" __declspec(...) warning C4768 now on by


default
The warning was added in Visual Studio 2017 version 15.3, but was off by default. In
Visual Studio 2017 version 15.5, the warning is on by default. For more information, see
New warning on __declspec attributes.

Defaulted functions and __declspec(nothrow)


The compiler previously allowed defaulted functions to be declared with
__declspec(nothrow) when the corresponding base/member functions permitted

exceptions. This behavior is contrary to the C++ standard and can cause undefined
behavior at runtime. The standard requires such functions to be defined as deleted if
there's an exception specification mismatch. Under /std:c++17 , the following code
raises C2280:

C++

struct A {
A& operator=(const A& other) { // No exception specification; this
function may throw.
...
}
};

struct B : public A {
__declspec(nothrow) B& operator=(const B& other) = default;
};
int main()
{
B b1, b2;
b2 = b1; // error C2280: attempting to reference a deleted function.
// Function was implicitly deleted because the explicit
exception
// specification is incompatible with that of the implicit
declaration.
}

To correct this code, either remove __declspec(nothrow) from the defaulted function, or
remove = default and provide a definition for the function along with any required
exception handling:

C++

struct A {
A& operator=(const A& other) {
// ...
}
};

struct B : public A {
B& operator=(const B& other) = default;
};

int main()
{
B b1, b2;
b2 = b1;
}

noexcept and partial specializations

With noexcept in the type system, partial specializations for matching particular
"callable" types may not compile, or fail to choose the primary template, because of a
missing partial specialization for pointers-to-noexcept-functions.

In such cases, you may need to add more partial specializations to handle the noexcept
function pointers and noexcept pointers to member functions. These overloads are only
legal in /std:c++17 mode or later. If backwards-compatibility with C++14 must be
maintained, and you're writing code that others consume, then you should guard these
new overloads inside #ifdef directives. If you're working in a self-contained module,
then instead of using #ifdef guards you can just compile with the /Zc:noexceptTypes-
switch.
The following code compiles under /std:c++14 but fails under /std:c++17 with error
C2027:

C++

template <typename T> struct A;

template <>
struct A<void(*)()>
{
static const bool value = true;
};

template <typename T>


bool g(T t)
{
return A<T>::value;
}

void f() noexcept {}

int main()
{
return g(&f) ? 0 : 1; // C2027: use of undefined type 'A<T>'
}

The following code succeeds under /std:c++17 because the compiler chooses the new
partial specialization A<void (*)() noexcept> :

C++

template <typename T> struct A;

template <>
struct A<void(*)()>
{
static const bool value = true;
};

template <>
struct A<void(*)() noexcept>
{
static const bool value = true;
};

template <typename T>


bool g(T t)
{
return A<T>::value;
}
void f() noexcept {}

int main()
{
return g(&f) ? 0 : 1; // OK
}

Conformance improvements in 15.6

C++17 Library Fundamentals V1


P0220R1 incorporates Library Fundamentals Technical Specification for C++17 into
the standard. Covers updates to <experimental/tuple> , <experimental/optional> ,
<experimental/functional> , <experimental/any> , <experimental/string_view> ,

<experimental/memory> , <experimental/memory_resource> , and


<experimental/algorithm> .

C++17: Improving class template argument deduction for


the standard library
P0739R0 Move adopt_lock_t to front of parameter list for scoped_lock to enable
consistent use of scoped_lock . Allow std::variant constructor to participate in
overload resolution in more cases, to enable copy assignment.

Conformance improvements in 15.7

C++17: Rewording inheriting constructors


P0136R1 specifies that a using declaration that names a constructor now makes the
corresponding base class constructors visible to initializations of the derived class, rather
than declaring more derived class constructors. This rewording is a change from C++14.
In Visual Studio 2017 version 15.7 and later, in /std:c++17 mode and later, code that is
valid in C++14 and uses inheriting constructors may not be valid, or may have different
semantics.

The following example shows C++14 behavior:

C++
struct A {
template<typename T>
A(T, typename T::type = 0);
A(int);
};

struct B : A {
using A::A;
B(int n) = delete; // Error C2280
};

B b(42L); // Calls B<long>(long), which calls A(int)


// due to substitution failure in A<long>(long).

The following example shows /std:c++17 behavior in Visual Studio 15.7:

C++

struct A {
template<typename T>
A(T, typename T::type = 0);
A(int);
};

struct B : A {
using A::A;
B(int n)
{
//do something
}
};

B b(42L); // now calls B(int)

For more information, see Constructors.

C++17: Extended aggregate initialization


P0017R1

If the constructor of a base class is non-public, but accessible to a derived class, then
under /std:c++17 mode and later in Visual Studio 2017 version 15.7, you can no longer
use empty braces to initialize an object of the derived type. The following example
shows C++14 conforming behavior:

C++
struct Derived;
struct Base {
friend struct Derived;
private:
Base() {}
};

struct Derived : Base {};


Derived d1; // OK. No aggregate init involved.
Derived d2 {}; // OK in C++14: Calls Derived::Derived()
// which can call Base ctor.

In C++17, Derived is now considered an aggregate type. It means that the initialization
of Base via the private default constructor happens directly, as part of the extended
aggregate initialization rule. Previously, the Base private constructor was called via the
Derived constructor, and it succeeded because of the friend declaration. The following

example shows C++17 behavior in Visual Studio version 15.7 in /std:c++17 mode:

C++

struct Derived;
struct Base {
friend struct Derived;
private:
Base() {}
};
struct Derived : Base {
Derived() {} // add user-defined constructor
// to call with {} initialization
};
Derived d1; // OK. No aggregate init involved.
Derived d2 {}; // error C2248: 'Base::Base': cannot access
// private member declared in class 'Base'

C++17: Declaring non-type template parameters with


auto
P0127R2

In /std:c++17 mode, the compiler can now deduce the type of a non-type template
argument that is declared with auto :

C++

template <auto x> constexpr auto constant = x;


auto v1 = constant<5>; // v1 == 5, decltype(v1) is int
auto v2 = constant<true>; // v2 == true, decltype(v2) is bool
auto v3 = constant<'a'>; // v3 == 'a', decltype(v3) is char

One effect of this new feature is that valid C++14 code may not be valid or may have
different semantics. For example, some overloads that were previously invalid are now
valid. The following example shows C++14 code that compiles because the call to
example(p) is bound to example(void*); . In Visual Studio 2017 version 15.7, in

/std:c++17 mode, the example function template is the best match.

C++

template <int N> struct A;


template <typename T, T N> int example(A<N>*) = delete;

void example(void *);

void sample(A<0> *p)


{
example(p); // OK in C++14
}

The following example shows C++17 code in Visual Studio 15.7 in /std:c++17 mode:

C++

template <int N> struct A;


template <typename T, T N> int example(A<N>*);

void example(void *);

void sample(A<0> *p)


{
example(p); // C2280: 'int example<int,0>(A<0>*)': attempting to
reference a deleted function
}

C++17: Elementary string conversions (partial)


P0067R5 Low-level, locale-independent functions for conversions between integers
and strings and between floating-point numbers and strings.

C++20: Avoiding unnecessary decay (partial)


P0777R1 Adds differentiation between the concept of "decay" and that of simply
removing const or reference qualifiers. New type trait remove_reference_t replaces
decay_t in some contexts. Support for remove_cvref_t is implemented in Visual Studio

2019.

C++17: Parallel algorithms


P0024R2 The Parallelism TS is incorporated into the standard, with minor
modifications.

C++17: hypot(x, y, z)
P0030R1 Adds three new overloads to std::hypot , for types float , double , and long
double , each of which has three input parameters.

C++17: <filesystem>
P0218R1 Adopts the File System TS into the standard with a few wording
modifications.

C++17: Mathematical special functions


P0226R1 Adopts previous technical specifications for Mathematical Special Functions
into the standard <cmath> header.

C++17: Deduction guides for the standard library


P0433R2 Updates to STL to take advantage of C++17 adoption of P0091R3 , which
adds support for class template argument deduction.

C++17: Repairing elementary string conversions


P0682R1 Move the new elementary string conversion functions from P0067R5 into a
new header <charconv> and make other improvements, including changing error
handling to use std::errc instead of std::error_code .

C++17: constexpr for char_traits (partial)


P0426R1 Changes to std::traits_type member functions length , compare , and find
to make std::string_view usable in constant expressions. (In Visual Studio 2017 version
15.6, supported for Clang/LLVM only. In version 15.7, support is nearly complete for
ClXX as well.)

C++17: Default argument in the primary class template


This behavior change is a precondition for P0091R3 - Template argument deduction for
class templates .

Previously, the compiler ignored the default argument in the primary class template:

C++

template<typename T>
struct S {
void f(int = 0);
};

template<typename T>
void S<T>::f(int = 0) {} // Re-definition necessary

In /std:c++17 mode in Visual Studio 2017 version 15.7, the default argument isn't
ignored:

C++

template<typename T>
struct S {
void f(int = 0);
};

template<typename T>
void S<T>::f(int) {} // Default argument is used

Dependent name resolution


This behavior change is a precondition for P0091R3 - Template argument deduction for
class templates .

In the following example, the compiler in Visual Studio 15.6 and earlier resolves D::type
to B<T>::type in the primary class template.

C++
template<typename T>
struct B {
using type = T;
};

template<typename T>
struct D : B<T*> {
using type = B<T*>::type;
};

Visual Studio 2017 version 15.7, in /std:c++17 mode, requires the typename keyword in
the using statement in D. Without typename , the compiler raises warning C4346:
'B<T*>::type': dependent name is not a type and error C2061: syntax error:
identifier 'type' :

C++

template<typename T>
struct B {
using type = T;
};

template<typename T>
struct D : B<T*> {
using type = typename B<T*>::type;
};

C++17: [[nodiscard]] attribute - warning level increase


In Visual Studio 2017 version 15.7 in /std:c++17 mode, the warning level of C4834 is
increased from W3 to W1. You can disable the warning with a cast to void , or by
passing /wd:4834 to the compiler.

C++

[[nodiscard]] int f() { return 0; }

int main() {
f(); // warning C4834: discarding return value
// of function with 'nodiscard'
}

Variadic template constructor base class initialization list


In previous editions of Visual Studio, a variadic template constructor base class
initialization list that was missing template arguments was erroneously allowed without
error. In Visual Studio 2017 version 15.7, a compiler error is raised.

The following code example in Visual Studio 2017 version 15.7 raises error C2614:

C++

template<typename T>
struct B {};

template<typename T>
struct D : B<T>
{

template<typename ...C>
D() : B() {} // C2614: D<int>: illegal member initialization: 'B' is not
a base or member
};

D<int> d;

To fix the error, change the B() expression to B<T>() .

constexpr aggregate initialization

Previous versions of the C++ compiler incorrectly handled constexpr aggregate


initialization. The compiler accepted invalid code in which the aggregate-init-list had too
many elements, and produced bad object code for it. The following code is an example
of such code:

C++

#include <array>
struct X {
unsigned short a;
unsigned char b;
};

int main() {
constexpr std::array<X, 2> xs = { // C2078: too many initializers
{ 1, 2 },
{ 3, 4 }
};
return 0;
}
In Visual Studio 2017 version 15.7 update 3 and later, the previous example now raises
C2078. The following example shows how to fix the code. When initializing a std::array
with nested brace-init-lists, give the inner array a braced-list of its own:

C++

#include <array>
struct X {
unsigned short a;
unsigned char b;
};

int main() {
constexpr std::array<X, 2> xs = {{ // note double braces
{ 1, 2 },
{ 3, 4 }
}}; // note double braces
return 0;
}

Conformance improvements in 15.8

typename on unqualified identifiers

In /permissive- mode, spurious typename keywords on unqualified identifiers in alias


template definitions are no longer accepted by the compiler. The following code now
produces C7511:

C++

template <typename T>


using X = typename T; // C7511: 'T': 'typename' keyword must be
// followed by a qualified name

To fix the error, change the second line to using X = T; .

__declspec() on right side of alias template definitions

__declspec is no longer permitted on the right-hand-side of an alias template definition.


Previously, the compiler accepted but ignored this code. It would never result in a
deprecation warning when the alias was used.

The standard C++ attribute [[deprecated]] may be used instead, and is respected in
Visual Studio 2017 version 15.6. The following code now produces C2760:
C++

template <typename T>


using X = __declspec(deprecated("msg")) T; // C2760: syntax error:
// unexpected token '__declspec',
// expected 'type specifier'`

To fix the error, change to code to the following (with the attribute placed before the '='
of the alias definition):

C++

template <typename T>


using X [[deprecated("msg")]] = T;

Two-phase name lookup diagnostics


Two-phase name lookup requires that non-dependent names used in template bodies
must be visible to the template at definition time. Previously, the Microsoft C++
compiler would leave an unfound name as not looked up until instantiation time. Now,
it requires that non-dependent names are bound in the template body.

One way this can manifest is with lookup into dependent base classes. Previously, the
compiler allowed the use of names that are defined in dependent base classes. It's
because they'd be looked up during instantiation time when all the types are resolved.
Now that code is treated as an error. In these cases, you can force the variable to be
looked up at instantiation time by qualifying it with the base class type or otherwise
making it dependent, for example, by adding a this-> pointer.

In /permissive- mode, the following code now raises C3861:

C++

template <class T>


struct Base {
int base_value = 42;
};

template <class T>


struct S : Base<T> {
int f() {
return base_value; // C3861: 'base_value': identifier not found
}
};
To fix the error, change the return statement to return this->base_value; .

7 Note

In Boost.Python library versions before 1.70, there's been an MSVC-specific


workaround for a template forward declaration in unwind_type.hpp . Under
/permissive- mode starting in Visual Studio 2017 version 15.8 ( _MSC_VER==1915 ), the
MSVC compiler does argument-dependent name lookup (ADL) correctly. It's now
consistent with other compilers, making this workaround guard unnecessary. To
avoid error C3861: 'unwind_type': identifier not found , update your
Boost.Python library.

forward declarations and definitions in namespace std


The C++ standard doesn't allow a user to add forward declarations or definitions into
namespace std . Adding declarations or definitions to namespace std or to a
namespace within namespace std now results in undefined behavior.

At some time in the future, Microsoft will move the location where some standard
library types are defined. This change will break existing code that adds forward
declarations to namespace std . A new warning, C4643, helps identify such source
issues. The warning is enabled in /default mode and is off by default. It will affect
programs that are compiled with /Wall or /WX .

The following code now raises C4643:

C++

namespace std {
template<typename T> class vector; // C4643: Forward declaring 'vector'
// in namespace std is not permitted
// by the C++ Standard`
}

To fix the error, use a #include directive rather than a forward declaration:

C++

#include <vector>

Constructors that delegate to themselves


The C++ standard suggests that a compiler should emit a diagnostic when a delegating
constructor delegates to itself. The Microsoft C++ compiler in /std:c++17 and
/std:c++latest modes now raises C7535.

Without this error, the following program will compile but will generate an infinite loop:

C++

class X {
public:
X(int, int);
X(int v) : X(v){} // C7535: 'X::X': delegating constructor calls itself
};

To avoid the infinite loop, delegate to a different constructor:

C++

class X {
public:

X(int, int);
X(int v) : X(v, 0) {}
};

offsetof with constant expressions

offsetof has traditionally been implemented using a macro that requires a


reinterpret_cast. This usage is illegal in contexts that require a constant expression, but
the Microsoft C++ compiler has traditionally allowed it. The offsetof macro that is
shipped as part of the standard library correctly uses a compiler intrinsic
( __builtin_offsetof ), but many people have used the macro trick to define their own
offsetof .

In Visual Studio 2017 version 15.8, the compiler constrains the areas that these
reinterpret_cast operators can appear in the default mode, to help code conform to

standard C++ behavior. Under /permissive-, the constraints are even stricter. Using the
result of an offsetof in places that require constant expressions may result in code that
issues warning C4644 or C2975.

The following code raises C4644 in default and /std:c++17 modes, and C2975 in
/permissive- mode:

C++
struct Data {
int x;
};

// Common pattern of user-defined offsetof


#define MY_OFFSET(T, m) (unsigned long long)(&(((T*)nullptr)->m))

int main()

{
switch (0) {
case MY_OFFSET(Data, x): return 0; // C4644: usage of the
// macro-based offsetof pattern in constant expressions
// is non-standard; use offsetof defined in the C++
// standard library instead
// OR
// C2975: invalid template argument, expected
// compile-time constant expression

default: return 1;
}
}

To fix the error, use offsetof as defined via <cstddef> :

C++

#include <cstddef>

struct Data {
int x;
};

int main()
{
switch (0) {
case offsetof(Data, x): return 0;
default: return 1;
}
}

cv-qualifiers on base classes subject to pack expansion


Previous versions of the Microsoft C++ compiler didn't detect that a base-class had cv-
qualifiers if it was also subject to pack expansion.

In Visual Studio 2017 version 15.8, in /permissive- mode, the following code raises
C3770:
C++

template<typename... T>
class X : public T... { };

class S { };

int main()
{
X<const S> x; // C3770: 'const S': is not a valid base class
}

template keyword and nested-name-specifiers

In /permissive- mode, the compiler now requires the template keyword to precede a
template-name when it comes after a dependent nested-name-specifier.

The following code in /permissive- mode now raises C7510:

C++

template<typename T> struct Base


{
template<class U> void example() {}
};

template<typename T>
struct X : Base<T>
{
void example()
{
Base<T>::example<int>(); // C7510: 'example': use of dependent
// template name must be prefixed with 'template'
// note: see reference to class template instantiation
// 'X<T>' being compiled
}
};

To fix the error, add the template keyword to the Base<T>::example<int>(); statement,
as shown in the following example:

C++

template<typename T> struct Base


{
template<class U> void example() {}
};

template<typename T>
struct X : Base<T>
{
void example()
{
// Add template keyword here:
Base<T>::template example<int>();
}
};

Conformance improvements in 15.9

Left-to-right evaluation order for operators ->* , [] , >> ,


and <<
Starting in C++17, the operands of the operators ->* , [] , >> , and << must be
evaluated in left-to-right order. There are two cases in which the compiler is unable to
guarantee this order:

when one of the operand expressions is an object passed by value or contains an


object passed by value, or

when compiled by using /clr , and one of the operands is a field of an object or an
array element.

The compiler emits warning C4866 when it can't guarantee left-to-right evaluation. The
compiler generates this warning only if /std:c++17 or later is specified, as the left-to-
right order requirement of these operators was introduced in C++17.

To resolve this warning, first consider whether left-to-right evaluation of the operands is
necessary. For example, it could be necessary when evaluation of the operands might
produce order-dependent side-effects. The order in which operands are evaluated has
no observable effect in many cases. If the order of evaluation must be left-to-right,
consider whether you can pass the operands by const reference instead. This change
eliminates the warning in the following code sample:

C++

// C4866.cpp
// compile with: /w14866 /std:c++17

class HasCopyConstructor
{
public:
int x;
HasCopyConstructor(int x) : x(x) {}
HasCopyConstructor(const HasCopyConstructor& h) : x(h.x) { }
};

int operator>>(HasCopyConstructor a, HasCopyConstructor b) { return a.x >>


b.x; }

// This version of operator>> does not trigger the warning:


// int operator>>(const HasCopyConstructor& a, const HasCopyConstructor& b)
{ return a.x >> b.x; }

int main()
{
HasCopyConstructor a{ 1 };
HasCopyConstructor b{ 2 };

a>>b; // C4866 for call to operator>>


};

Identifiers in member alias templates


An identifier used in a member alias template definition must be declared before use.

In previous versions of the compiler, the following code was allowed. In Visual Studio
2017 version 15.9, in /permissive- mode, the compiler raises C3861:

C++

template <typename... Ts>


struct A
{
public:
template <typename U>
using from_template_t = decltype(from_template(A<U>{})); // C3861:
// 'from_template': identifier not found

private:
template <template <typename...> typename Type, typename... Args>
static constexpr A<Args...> from_template(A<Type<Args...>>);
};

A<>::from_template_t<A<int>> a;

To fix the error, declare from_template before from_template_t .

Modules changes
In Visual Studio 2017, version 15.9, the compiler raises C5050 whenever the command-
line options for modules aren't consistent between the module creation and module
consumption sides. In the following example, there are two issues:

On the consumption side (main.cpp), the option /EHsc isn't specified.

The C++ version is /std:c++17 on the creation side, and /std:c++14 on the
consumption side.

Windows Command Prompt

cl /EHsc /std:c++17 m.ixx /experimental:module


cl /experimental:module /module:reference m.ifc main.cpp /std:c++14

The compiler raises C5050 for both of these cases:

Output

warning C5050: Possible incompatible environment while


importing module 'm': mismatched C++ versions.
Current "201402" module version "201703".

The compiler also raises C7536 whenever the .ifc file has been tampered with. The
header of the module interface contains an SHA2 hash of the contents below it. On
import, the .ifc file is hashed, then checked against the hash provided in the header. If
these don't match, error C7536 is raised:

Output

error C7536: ifc failed integrity checks.


Expected SHA2:
'66d5c8154df0c71d4cab7665bab4a125c7ce5cb9a401a4d8b461b706ddd771c6'

Partial ordering involving aliases and non-deduced


contexts
Implementations diverge in the partial ordering rules involving aliases in non-deduced
contexts. In the following example, GCC and the Microsoft C++ compiler (in
/permissive- mode) raise an error, while Clang accepts the code.

C++

#include <utility>
using size_t = std::size_t;
template <typename T>
struct A {};
template <size_t, size_t>
struct AlignedBuffer {};
template <size_t len>
using AlignedStorage = AlignedBuffer<len, 4>;

template <class T, class Alloc>


int f(Alloc &alloc, const AlignedStorage<T::size> &buffer)
{
return 1;
}

template <class T, class Alloc>


int f(A<Alloc> &alloc, const AlignedStorage<T::size> &buffer)
{
return 2;
}

struct Alloc
{
static constexpr size_t size = 10;
};

int main()
{
A<void> a;
AlignedStorage<Alloc::size> buf;
if (f<Alloc>(a, buf) != 2)
{
return 1;
}

return 0;
}

The previous example raises C2668:

Output

partial_alias.cpp(32): error C2668: 'f': ambiguous call to overloaded


function
partial_alias.cpp(18): note: could be 'int f<Alloc,void>(A<void> &,const
AlignedBuffer<10,4> &)'
partial_alias.cpp(12): note: or 'int f<Alloc,A<void>>(Alloc &,const
AlignedBuffer<10,4> &)'
with
[
Alloc=A<void>
]
partial_alias.cpp(32): note: while trying to match the argument list
'(A<void>, AlignedBuffer<10,4>)'

The implementation divergence is because of a regression in the C++ standard wording.


The resolution to core issue 2235 removed some text that would allow these overloads
to be ordered. The current C++ standard doesn't provide a mechanism to partially order
these functions, so they're considered ambiguous.

As a workaround, we recommended that you not rely on partial ordering to resolve this
problem. Instead, use SFINAE to remove particular overloads. In the following example,
we use a helper class IsA to remove the first overload when Alloc is a specialization of
A:

C++

#include <utility>
using size_t = std::size_t;

template <typename T>


struct A {};
template <size_t, size_t>
struct AlignedBuffer {};
template <size_t len>
using AlignedStorage = AlignedBuffer<len, 4>;

template <typename T> struct IsA : std::false_type {};


template <typename T> struct IsA<A<T>> : std::true_type {};

template <class T, class Alloc, typename =


std::enable_if_t<!IsA<Alloc>::value>>
int f(Alloc &alloc, const AlignedStorage<T::size> &buffer)
{
return 1;
}

template <class T, class Alloc>


int f(A<Alloc> &alloc, const AlignedStorage<T::size> &buffer)
{
return 2;
}

struct Alloc
{
static constexpr size_t size = 10;
};

int main()
{
A<void> a;
AlignedStorage<Alloc::size> buf;
if (f<Alloc>(a, buf) != 2)
{
return 1;
}

return 0;
}

Illegal expressions and non-literal types in templated


function definitions
Illegal expressions and non-literal types are now correctly diagnosed in the definitions
of templated functions that are explicitly specialized. Previously, such errors weren't
emitted for the function definition. However, the illegal expression or non-literal type
would still have been diagnosed if evaluated as part of a constant expression.

In previous versions of Visual Studio, the following code compiles without warning:

C++

void g();

template<typename T>
struct S
{
constexpr void f();
};

template<>
constexpr void S<int>::f()
{
g(); // C3615 in 15.9
}

In Visual Studio 2017 version 15.9, the code raises error C3615:

Output

error C3615: constexpr function 'S<int>::f' cannot result in a constant


expression.
note: failure was caused by call of undefined function or one not declared
'constexpr'
note: see usage of 'g'.

To avoid the error, remove the constexpr qualifier from the explicit instantiation of the
function f() .
See also
Microsoft C/C++ language conformance
Microsoft C/C++ language conformance
by Visual Studio version
Article • 03/02/2023

Standards conformance for the Microsoft C/C++ compiler in Visual Studio (MSVC) is a
work in progress. Here's a summary of ISO Standard C and C++ language and library
conformance by Visual Studio version. Each C++ compiler and standard library feature
name has a link to the ISO Standard C++ proposal paper that describes the feature,
when one is available at publication time. The Supported column lists the Visual Studio
version in which support for the feature first appeared.

For details on conformance improvements, see C++ conformance improvements in


Visual Studio. For a list of other changes, see What's New for Visual C++ in Visual
Studio. For conformance changes in earlier versions, see Visual C++ change history and
Visual C++ What's New 2003 through 2015. For current news from the C++ team, visit
the C++ team blog .

7 Note

There are no binary breaking changes between Visual Studio 2015, 2017, 2019, and
2022. For more information, see C++ binary compatibility between Visual Studio
versions

C++ compiler features


ノ Expand table

Feature Supported

C++03/11 Core language features Supported

Everything else VS 2015 A

Two-phase name lookup VS 2017 15.7 B

N2634 Expression SFINAE VS 2017 15.7

N1653 C99 preprocessor VS 2019 16.6 C

C++03/11 Core language features (Defect reports) Supported

C++14 Core language features Supported


Feature Supported

N3323 Tweaked wording for contextual VS 2013


conversions

N3472 Binary literals VS 2015

N3638 auto and decltype(auto) return types VS 2015

N3648 init-captures VS 2015

N3649 Generic lambdas VS 2015

N3760 [[deprecated]] attribute VS 2015

N3778 Sized deallocation VS 2015

N3781 Digit separators VS 2015

N3651 Variable templates VS 2015 Update 2

N3652 Extended constexpr VS 2017 15.0

N3653 Default member initializers for aggregates VS 2017 15.0

C++17 Core language features Supported

N4086 Removing trigraphs VS 2010 14

N3922 New rules for auto with braced-init-lists VS 2015 14

N4051 typename in template template- VS 2015 14


parameters

N4266 Attributes for namespaces and VS 2015 14


enumerators

N4267 u8 character literals VS 2015 14

N4230 Nested namespace definitions VS 2015.3 17

N3928 Terse static_assert VS 2017 15.0 17

P0184R0 Generalized range-based for-loops VS 2017 15.0 14

P0188R1 [[fallthrough]] attribute VS 2017 15.0 17

P0001R1 Removing the register keyword VS 2017 15.3 17

P0002R1 Removing operator++ for bool VS 2017 15.3 17

P0018R3 Capturing *this by value VS 2017 15.3 17


Feature Supported

P0028R4 Using attribute namespaces without VS 2017 15.3 17


repetition

P0061R1 __has_include VS 2017 15.3 14

P0138R2 Direct-list-init of fixed enums from VS 2017 15.3 17


integers

P0170R1 constexpr lambdas VS 2017 15.3 17

P0189R1 [[nodiscard]] attribute VS 2017 15.3 17

P0212R1 [[maybe_unused]] attribute VS 2017 15.3 17

P0217R3 Structured bindings VS 2017 15.3 17

P0292R2 constexpr if-statements VS 2017 15.3 D

P0305R1 Selection statements with initializers VS 2017 15.3 17

P1381R1 Reference capture of structured VS 2017 15.3 17


bindings

P0245R1 Hexfloat literals VS 2017 15.5 17

N4268 Allowing more non-type template args VS 2017 15.5 17

N4295 Fold expressions VS 2017 15.5 17

P0003R5 Removing dynamic-exception- VS 2017 15.5 17


specifications

P0012R1 Adding noexcept to the type system VS 2017 15.5 17

P0035R4 Over-aligned dynamic memory VS 2017 15.5 17


allocation

P0386R2 Inline variables VS 2017 15.5 17

P0522R0 Matching template template-parameters VS 2017 15.5 17


to compatible arguments

P0036R0 Removing some empty unary folds VS 2017 15.5 17

N4261 Fixing qualification conversions VS 2017 15.7 17

P0017R1 Extended aggregate initialization VS 2017 15.7 17

P0091R3 Template argument deduction for class VS 2017 15.7 17


templates
Feature Supported

P0512R0 Class template argument deduction


issues

P0127R2 Declaring non-type template VS 2017 15.7 17


parameters with auto

P0135R1 Guaranteed copy elision VS 2017 15.6

P0136R1 Rewording inheriting constructors VS 2017 15.7 17

P0137R1 std::launder VS 2017 15.7 17

P0145R3 Refining expression evaluation order VS 2017 15.7 17


P0400R0 Order of evaluation of function
arguments

P0195R2 Pack expansions in using-declarations VS 2017 15.7 17

P0283R2 Ignoring unrecognized attributes VS 2015 14

C++17 Core language features (Defect reports) Supported

P0702R1 Fixing class template argument VS 2017 15.7 17


deduction for initializer-list ctors

P0961R1 Relaxing the structured bindings VS 2019 16.0 17


customization point finding rules

P0969R0 Allowing structured bindings to VS 2019 16.0 17


accessible members

P0588R1 Simplifying implicit lambda capture VS 2019 16.4 17

P1771R1 [[nodiscard]] for constructors VS 2019 16.4 17

P1825R0 Merged wording for P0527R1 and VS 2019 16.4 17


P1155R3, more implicit moves

P0929R2 Checking for abstract class types VS 2019 16.5 17

P0962R1 Relaxing the range-for loop VS 2019 16.5 17


customization point finding rules

P0859R0 CWG 1581: When are constexpr Partial in VS 2019 16.7 E


member functions defined

P1009R2 Array size deduction in new-expressions VS 2019 16.7 17

P1286R2 Contra CWG DR1778 VS 2019 16.8 17

C++20 Core language features Supported


Feature Supported

P0641R2 const mismatch with defaulted copy VS 2015 14


constructor

P0704R1 Fixing const lvalue ref-qualified pointers VS 2015 14


to members

P1041R4 Make char16_t/char32_t string literals be VS 2015 14


UTF-16/32

P1330R0 Changing the active member of a union VS 2017 15.0 14


inside constexpr

P0972R0 noexcept For <chrono> zero(), min(), VS 2017 15.7 14


max()

P0515R3 Three-way (spaceship) comparison VS 2019 16.0 20


operator <=>

P0941R2 Feature-test macros VS 2019 16.0 14

P1008R1 Prohibiting aggregates with user- VS 2019 16.0 20


declared constructors

P0329R4 Designated initialization VS 2019 16.1 20

P0846R0 ADL and function templates that are not VS 2019 16.1 20
visible

P0409R2 Allowing lambda-capture [=, this] VS 2019 16.2 20

P0428R2 Familiar template syntax for generic VS 2019 16.2 20


lambdas

P0624R2 Default constructible and assignable VS 2019 16.2 20


stateless lambdas

P0780R2 Allowing pack expansion in lambda init- VS 2019 16.2 20


capture

P0806R2 Deprecate implicit capture of this via [=] VS 2019 16.2 20

P1120R0 Consistency improvements for <=> and VS 2019 16.2 20


other comparison operators

P1185R2 <=> != == VS 2019 16.2 20

P0734R0 Concepts VS 2019 16.3 20

P0857R0 Fixing functionality gaps in constraints VS 2019 16.3 20


Feature Supported

P1084R2 Today's return-type-requirements are VS 2019 16.3 20


insufficient

P0892R2 Conditional explicit VS 2019 16.4 20

P1091R3 Extending structured bindings to be VS 2019 16.4 20


more like variable declarations

P1099R5 Using enum VS 2019 16.4 20

P1186R3 When do you actually use <=> VS 2019 16.4 20

P1630R1 Spaceship needs a tune-up VS 2019 16.4 20

P0306R4 Adding __VA_OPT__ for comma omission VS 2019 16.5. To provide better backward
and comma deletion compatibility, __VA_OPT__ is enabled under
/Zc:preprocessor across all language
versions.

P0614R1 Range-based for-loops with initializers VS 2019 16.5 20

P0683R1 Default member initializers for bit-fields VS 2019 16.5 20

P1002R1 try-catch blocks in constexpr functions VS 2019 16.5 20

P1161R3 Deprecate uses of the comma operator VS 2019 16.5 20


in subscripting expressions

P1301R4 [[nodiscard("message")]] VS 2019 16.5 20

P1703R1 Recognizing header unit imports VS 2019 16.5 20


requires full preprocessing

P1946R0 Allow defaulting comparisons by value VS 2019 16.5 20

P0479R5 [[likely]] and [[unlikely]] attributes VS 2019 16.6 20

P0692R1 Relaxing access checking on VS 2019 16.6 14


specializations

P0732R2 Class types in non-type template VS 2019 16.6 20


parameters

P1139R2 Address wording issues related to ISO VS 2019 16.6 14


10646

P1907R1 Inconsistencies with non-type template VS 2019 16.6 20


parameters

P1971R0 US053: Mandate the return type for VS 2019 16.6 20


Feature Supported

return_void and return_value to be void

P1971R0 US065: Apply Coroutines issue 24 from VS 2019 16.6 20


P0664R8

P1979R0 Resolution to US086 VS 2019 16.6 20

P0388R4 Permit conversions to arrays of unknown VS 2019 16.7 20


bound

P0466R5 Layout-compatibility and Pointer- VS 2019 16.7 20


interconvertibility Traits

P0722R3 Efficient sized delete for variable sized VS 2019 16.7 20


classes

P1094R2 Nested inline namespaces VS 2019 16.7 20

P1152R4 Deprecating volatile VS 2019 16.7 20

P1331R2 Permitting trivial default initialization in VS 2019 16.7 20


constexpr contexts

P1358R0 2310: Type completeness and derived- VS 2019 16.7 20


to-base pointer conversions

P1452R2 On the non-uniform semantics of VS 2019 16.7 20


return-type-requirements

P1616R1 Using unconstrained TTPs with VS 2019 16.7 20


constrained templates

P1814R0 CTAD for alias templates VS 2019 16.7 20

P1816R0 CTAD for aggregates VS 2019 16.7 20

P1957R1 Converting from T* to bool should be VS 2019 16.7 DR


considered narrowing (re: US 212)

P1968R0 CWG 2282: Consistency with VS 2019 16.7 20


mismatched aligned/non-over-aligned
allocation/deallocation functions

P1969R0 CWG 2280: Matching a usual VS 2019 16.7 20


deallocation function with placement new

P1969R0 CWG 2382: Array allocation overhead VS 2019 16.7 20


for non-allocating placement new

P1969R0 CWG 2441: Inline function parameters VS 2019 16.7 20


Feature Supported

P1971R0 US052: Non-executed return statements VS 2019 16.7 20


in coroutines

P1972R0 US105: Check satisfaction of constraints VS 2019 16.7 20


for non-templates when forming pointer to function

P1980R0 CA096: Declaration matching for non- VS 2019 16.7 20


dependent requires-clauses

P2082R1 Fixing CTAD for aggregates VS 2019 16.7 20

P2085R0 Consistent defaulted comparisons VS 2019 16.7 20

P2103R0 US033: Allow "import" inside linkage- VS 2019 16.7 20


specifications

P2107R0 US064: Copy semantics of coroutine VS 2019 16.7 20


parameters

P0912R5 Coroutines VS 2019 16.8 20

P1103R3 Modules VS 2019 16.8 20

P0315R4 Allowing lambdas in unevaluated VS 2019 16.8 20


contexts

P0848R3 Conditionally trivial special member VS 2019 16.8 20


functions

P0960R3 Allow initializing aggregates from a VS 2019 16.8 20


parenthesized list of values

P1766R1 Mitigating minor modules maladies VS 2019 16.8 20

P1811R0 Relaxing redefinition restrictions for re- VS 2019 16.8 20


exportation robustness

P1874R1 Dynamic Initialization Order of Non- VS 2019 16.8 20


Local Variables in Modules

P1975R0 Fixing the wording of parenthesized VS 2019 16.8 20


aggregate-initialization

P0634R3 Down with typename! VS 2019 16.9 20

P0784R7 More constexpr containers VS 2019 16.9 20

P0840R2 [[no_unique_address]] attribute VS 2019 16.9 20

P1064R0 Allowing virtual function calls in VS 2019 16.9 20


Feature Supported

constant expressions

P1141R2 Yet another approach for constrained VS 2019 16.9 20


declarations

P1327R1 Allowing dynamic_cast, polymorphic VS 2019 16.9 20


typeid in constant expressions

P1668R1 Permitting unevaluated inline assembly VS 2019 16.9 20


in constexpr functions

P1073R3 Immediate functions VS 2019 16.10 20

P1143R2 constinit VS 2019 16.10 20

P1353R0 Missing feature-test macros VS 2019 16.10 20

P0735R1 Interaction of memory_order_consume N/A


with release sequences

P1236R1 Signed integers are two's complement N/A

C++23 Core language features Supported

P0330R8 Literal Suffix for (signed) size_t no

P0847R7 Deducing this no

P0849R8 auto(x): decay-copy in the language no

P1102R2 Down with ()! no

P1169R4 static operator() no

P1401R5 Narrowing contextual conversions to no


bool

P1467R9 Extended floating-point types and no


standard names

P1774R8 Portable assumptions no

P1787R6 Declarations and where to find them no

P1847R4 Make declaration order layout VS 2022 17.0 23


mandated

P1938R3 if consteval no

P1949R7 C++ Identifier Syntax using Unicode no


Standard Annex 31
Feature Supported

P2029R4 Proposed resolution for core issues 411, no


1656, and 2333; numeric and universal character
escapes in character and string literals

P2036R3 Change scope of lambda trailing-return- no


type

P2071R2 Named universal character escapes no

P2128R6 Multidimensional subscript operator no

P2156R1 Allow Duplicate Attributes no

P2173R1 Attributes on Lambda-Expressions no

P2186R2 Remove Garbage Collection Support VS 2022 17.0 23

P2201R1 Mixed string literal concatenation no

P2223R2 Trimming whitespaces before line no


splicing

P2242R3 Non-literal variables (and labels and no


gotos) in constexpr functions

P2246R1 Character encoding of diagnostic text VS 2022 17.0 23

P2266R3 Simpler implicit move no

P2280R4 Using unknown pointers and references no


in constant expressions

P2290R3 Delimited escape sequences no

P2295R6 Support for UTF-8 as a portable source no


file encoding

P2314R4 Character sets and encodings no

P2316R2 Consistent character literal encoding VS 2022 17.0 23

P2324R2 Labels at the end of compound no


statements (C compatibility)

P2327R1 De-deprecating volatile compound no


operations

P2334R1 preprocessing directives elifdef and no


elifndef
Feature Supported

P2360R0 Extend init-statement to allow alias- no


declaration

P2362R3 Remove non-encodable wide character no


literals and multicharacter wide character literals

P2437R1 Support for #warning no

P2448R2 Relaxing some constexpr restrictions no

P2460R2 Relax requirements on wchar_t to match no


existing practices

P2468R2 The Equality Operator You Are Looking no


For

P2493R0 Missing feature test macros for C++20 no


core papers

P2493R0 Missing feature test macros for C++20 no


core papers

P2513R4 char8_t Compatibility and Portability Fix VS 2022 17.4 DR

P2579R0 Mitigation strategies for P2036 no


”Changing scope for lambda trailing-return-type”

P2582R1 Wording for class template argument no


deduction from inherited constructors

C++ Standard library features


A more detailed listing of Standard Library features and bug fixes by product version is
available on the GitHub Microsoft STL wiki Changelog page.

ノ Expand table

Feature Supported

C++14 Standard library features Supported

N3462 SFINAE-Friendly result_of VS 2015.2

N3302 constexpr For <complex> VS 2015

N3469 constexpr For <chrono> VS 2015


Feature Supported

N3470 constexpr For <array> VS 2015

N3471 constexpr For <initializer_list>, <tuple>, <utility> VS 2015

N3545 integral_constant::operator()() VS 2015

N3642 UDLs For <chrono>, <string> (1729ms, "meow"s, etc.) VS 2015

N3644 Null Forward Iterators VS 2015

N3654 quoted() VS 2015

N3657 Heterogeneous Associative Lookup VS 2015

N3658 integer_sequence VS 2015

N3659 shared_mutex (Timed) VS 2015

N3668 exchange() VS 2015

N3669 Fixing constexpr Member Functions Without const VS 2015

N3670 get<T>() VS 2015

N3671 Dual-Range equal(), is_permutation(), mismatch() VS 2015

N3778 Sized Deallocation VS 2015

N3779 UDLs For <complex> (3.14i, etc.) VS 2015

N3789 constexpr For <functional> VS 2015

N3887 tuple_element_t VS 2015

N3891 Renaming shared_mutex (Timed) To shared_timed_mutex VS 2015

N3346 Minimal Container Element Requirements VS 2013

N3421 Transparent Operator Functors (less<>, etc.) VS 2013

N3655 Alias Templates For <type_traits> (decay_t, etc.) VS 2013

N3656 make_unique() VS 2013

C++17 Standard library features Supported

N3911 void_t VS 2015 14

N4089 Safe Conversions In unique_ptr<T[]> VS 2015 14

N4169 invoke() VS 2015 14


Feature Supported

N4190 Removing auto_ptr, random_shuffle(), And Old <functional> Stuff VS 2015 F

N4258 noexcept Cleanups VS 2015 14

N4259 uncaught_exceptions() VS 2015 14

N4277 Trivially Copyable reference_wrapper VS 2015 14

N4279 insert_or_assign()/try_emplace() For map/unordered_map VS 2015 14

N4280 size(), empty(), data() VS 2015 14

N4366 Precisely Constraining unique_ptr Assignment VS 2015 14

N4387 Improving pair And tuple VS 2015.2 14

N4389 bool_constant VS 2015 14

N4508 shared_mutex (Untimed) VS 2015.2 14

N4510 Supporting Incomplete Types In vector/list/forward_list VS 2013 14

N4562 Library Fundamentals: <algorithm> sample() VS 2017 15.0

N4562 Library Fundamentals: <any> VS 2017 15.0

N4562 Library Fundamentals: <memory_resource> VS 2017 15.6


P0337R0 Deleting polymorphic_allocator Assignment

N4562 Library Fundamentals: <optional> VS 2017 15.0

N4562 Library Fundamentals: <string_view> VS 2017 15.0

N4562 Library Fundamentals: <tuple> apply() VS 2017 15.0

N4562 Library Fundamentals: Boyer-Moore search() VS 2017 15.3 17


P0253R1 Fixing Searcher Return Types

P0003R5 Removing Dynamic Exception Specifications VS 2017 15.5 17

P0004R1 Removing Deprecated Iostreams Aliases VS 2015.2 F

P0005R4 not_fn() VS 2017 15.5 17


P0358R1 Fixes For not_fn()

P0006R0 Variable Templates For Type Traits (is_same_v, etc.) VS 2015.2 14

P0007R1 as_const() VS 2015.2 14

P0013R1 Logical Operator Type Traits (conjunction, etc.) VS 2015.2 14


Feature Supported

P0024R2 Parallel Algorithms VS 2017 15.7 G


P0336R1 Renaming Parallel Execution Policies
P0394R4 Parallel Algorithms Should terminate() For Exceptions
P0452R1 Unifying <numeric> Parallel Algorithms

P0025R1 clamp() VS 2015.3

P0030R1 hypot(x, y, z) VS 2017 15.7

P0031R0 constexpr For <array> (Again) And <iterator> VS 2017 15.3 17

P0032R3 Homogeneous Interface For variant/any/optional VS 2017 15.0

P0033R1 Rewording enable_shared_from_this VS 2017 15.5 14

P0040R3 Extending Memory Management Tools VS 2017 15.3 17

P0063R3 C11 Standard Library VS 2015 C11, 14

P0067R5 Elementary String Conversions VS 2019 16.4

P0074R0 owner_less<> VS 2015.2 14

P0077R2 is_callable, is_nothrow_callable VS 2017 15.0

P0083R3 Splicing Maps And Sets VS 2017 15.5 17


P0508R0 Clarifying insert_return_type

P0084R2 Emplace Return Type VS 2017 15.3 17

P0088R3 <variant> VS 2017 15.0

P0092R1 <chrono> floor(), ceil(), round(), abs() VS 2015.2 14

P0152R1 atomic::is_always_lock_free VS 2017 15.3 17

P0154R1 hardware_destructive_interference_size, etc. VS 2017 15.3 17

P0156R0 Variadic lock_guard VS 2015.2 14

P0156R2 Renaming Variadic lock_guard to scoped_lock VS 2017 15.3 17

P0163R0 shared_ptr::weak_type VS 2017 15.0

P0174R2 Deprecating Vestigial Library Parts VS 2017 15.5 17

P0185R1 is_swappable, is_nothrow_swappable VS 2015.3

P0209R2 make_from_tuple() VS 2017 15.0

P0218R1 <filesystem> VS 2017 15.7 H


P0219R1 Relative Paths For Filesystem
Feature Supported

P0317R1 Directory Entry Caching For Filesystem


P0392R0 Supporting string_view In Filesystem Paths
P0430R2 Supporting Non-POSIX Filesystems
P0492R2 Resolving NB Comments for Filesystem

P0220R1 Library Fundamentals V1 VS 2017 15.6

P0226R1 Mathematical Special Functions VS 2017 15.7

P0254R2 Integrating string_view And std::string VS 2017 15.0

P0258R2 has_unique_object_representations VS 2017 15.3 I

P0272R1 Non-const basic_string::data() VS 2015.3

P0295R0 gcd(), lcm() VS 2017 15.3 17

P0298R3 std::byte VS 2017 15.3 17, J

P0302R1 Removing Allocator Support In std::function VS 2017 15.5 17

P0307R2 Making Optional Greater Equal Again VS 2017 15.0

P0393R3 Making Variant Greater Equal VS 2017 15.0

P0403R1 UDLs For <string_view> ("meow"sv, etc.) VS 2017 15.3 17

P0414R2 shared_ptr<T[]>, shared_ptr<T[N]> VS 2017 15.5 14


P0497R0 Fixing shared_ptr For Arrays

P0418R2 atomic compare_exchange memory_order Requirements VS 2017 15.3 14

P0426R1 constexpr For char_traits VS 2017 15.7

P0433R2 Integrating template deduction for class templates into the VS 2017 15.7
standard library
P0739R0 Improving class template argument deduction integration into
the standard library

P0435R1 Overhauling common_type VS 2017 15.3 14


P0548R1 Tweaking common_type and duration

P0504R0 Revisiting in_place_t/in_place_type_t<T>/in_place_index_t<I> VS 2017 15.0

P0505R0 constexpr For <chrono> (Again) VS 2017 15.3 17

P0510R0 Rejecting variants Of Nothing, Arrays, References, And VS 2017 15.0


Incomplete Types

P0513R0 Poisoning hash VS 2017 15.3 14


P0599R1 noexcept hash
Feature Supported

P0516R0 Marking shared_future Copying As noexcept VS 2017 15.3 14

P0517R0 Constructing future_error From future_errc VS 2017 15.3 14

P0521R0 Deprecating shared_ptr::unique() VS 2017 15.5 17

P0558R1 Resolving atomic<T> Named Base Class Inconsistencies VS 2017 15.3 14

P0595R2 std::is_constant_evaluated() VS 2019 16.5 20

P0602R4 Propagating Copy/Move Triviality In variant/optional VS 2017 15.317

P0604R0 Changing is_callable/result_of To invoke_result, is_invocable, VS 2017 15.3 17


is_nothrow_invocable

P0607R0 Inline Variables for the Standard Library VS 2017 15.5 17

P0618R0 Deprecating <codecvt> VS 2017 15.5 17

C++17 Standard library features (Defect reports) Supported

P0682R1 Repairing Elementary String Conversions VS 2015 15.7 17

P1164R1 Making create_directory() Intuitive VS 2019 16.0 14

C++20 Standard library features Supported

P0809R0 Comparing Unordered Containers VS 2010 14

P0858R0 Constexpr Iterator Requirements VS 2017 15.3 17

P0777R1 Avoiding Unnecessary Decay VS 2017 15.7 14

P0550R2 remove_cvref VS 2019 16.0 20

P0318R1 unwrap_reference, unwrap_ref_decay VS 2019 16.1 20

P0457R2 starts_with()/ends_with() For basic_string/basic_string_view VS 2019 16.1 20

P0458R2 contains() For Ordered And Unordered Associative Containers VS 2019 16.1 20

P0646R1 list/forward_list remove()/remove_if()/unique() Return size_type VS 2019 16.1 20

P0769R2 shift_left(), shift_right() VS 2019 16.1 20

P0887R1 type_identity VS 2019 16.1 20

P0020R6 atomic<float>, atomic<double>, atomic<long double> VS 2019 16.2 20

P0463R1 endian VS 2019 16.2 20

P0482R6 char8_t: A type for UTF-8 characters and strings VS 2019 16.2 20
Feature Supported

P0600R1 [[nodiscard]] For The STL, Part 1 VS 2019 16.2 20

P0653R2 to_address() VS 2019 16.2 20

P0754R2 <version> VS 2019 16.2 20

P0771R1 noexcept For std::function's Move Constructor VS 2019 16.2 20

P0487R1 Fixing operator>>(basic_istream&, CharT*) VS 2019 16.3 20

P0616R0 Using move() In <numeric> VS 2019 16.3 20

P0758R1 is_nothrow_convertible VS 2019 16.3 20

P0898R3 Standard Library Concepts VS 2019 16.3 20

P0919R3 Heterogeneous Lookup For Unordered Containers VS 2019 16.3 20

P1754R1 Rename Concepts to standard_case VS 2019 16.4 20

P0325R4 to_array from LFTS with updates VS 2019 16.5 20

P0340R3 SFINAE-Friendly underlying_type VS 2019 16.5 14

P0356R5 bind_front() VS 2019 16.5 20

P0439R0 enum class memory_order VS 2019 16.5 20

P0553R4 <bit> Rotating And Counting Functions VS 2019 16.5 20

P0556R3 <bit> ispow2(), ceil2(), floor2(), log2p1() VS 2019 16.5 20

P0595R2 is_constant_evaluated() VS 2019 16.5 20

P0631R8 <numbers> Math Constants VS 2019 16.5 20

P0655R1 visit<R>() VS 2019 16.5 20

P0738R2 istream_iterator Cleanup VS 2019 16.5 14

P0767R1 Deprecating is_pod VS 2019 16.5 20

P0966R1 string::reserve() Should Not Shrink VS 2019 16.5 20

P1209R0 erase_if(), erase() VS 2019 16.5 20

P1227R2 Signed std::ssize(), Unsigned span::size() VS 2019 16.5 20

P1355R2 Narrow Contract For ceil2() VS 2019 16.5 20

P1357R1 is_bounded_array, is_unbounded_array VS 2019 16.5 20


Feature Supported

P1612R1 Relocating endian To <bit> VS 2019 16.5 20

P1651R0 bind_front() Should Not Unwrap reference_wrapper VS 2019 16.5 20

P1690R1 Refining Heterogeneous Lookup For Unordered Containers VS 2019 16.5 20

P1902R1 Missing Feature-Test Macros 2017-2019 VS 2019 16.5 14

P0122R7 <span> VS 2019 16.6 20


P1024R3 Enhancing span usability
P1085R2 Removing span comparisons
P1394R4 Range constructor for span
P1872R0 span should have size_type, not index_type

P0202R3 constexpr for <algorithm> and exchange() VS 2019 16.6 20

P0357R3 Supporting Incomplete Types In reference_wrapper VS 2019 16.6 20

P0619R4 Removing C++17-Deprecated Features In C++20 VS 2019 16.6 20

P0879R0 constexpr for swapping functions VS 2019 16.6 20

P0883R2 Fixing atomic initialization VS 2019 16.6 14

P0935R0 Eradicating Unnecessarily Explicit Default Constructors VS 2019 16.6 14

P1006R1 constexpr For pointer_traits<T*>::pointer_to() VS 2019 16.6 20

P1165R1 Consistently Propagating Stateful Allocators In basic_string's VS 2019 16.6 14


operator+()

P1423R3 char8_t backward compatibility remediation VS 2019 16.6 20

P1645R1 constexpr for <numeric> algorithms VS 2019 16.6 20

P0415R1 constexpr For <complex> (Again) VS 2019 16.7 20

P0476R2 <bit> bit_cast VS 2019 16.7 20

P0528R3 Atomic Compare-And-Exchange With Padding Bits VS 2019 16.7 20

P0586R2 Integer comparison functions VS 2019 16.7 20

P0674R1 make_shared() For Arrays VS 2019 16.7 20

P0718R2 atomic<shared_ptr<T>>, atomic<weak_ptr<T>> VS 2019 16.7 20

P1023R0 constexpr For std::array Comparisons VS 2019 16.7 20

P1115R3 erase()/erase_if() Return size_type VS 2019 16.7 20


Feature Supported

P1831R1 Deprecating volatile in the standard library VS 2019 16.7 20

P1871R1 Concept traits should be named after concepts VS 2019 16.7 20

P1956R1 <bit> has_single_bit(), bit_ceil(), bit_floor(), bit_width() VS 2019 16.7 20

P1964R2 Replacing boolean With boolean-testable VS 2019 16.7 20

P1976R2 Fixed-size span construction from dynamic range VS 2019 16.7 20

P2091R0 Issues with range access CPOs VS 2019 16.7 20

P2102R0 Make "implicit expression variations" more explicit VS 2019 16.7 20

P2116R0 Remove tuple-like protocol support from fixed-extent span VS 2019 16.7 20

P0019R8 atomic_ref VS 2019 16.8 20

P0528R3 Library support for atomic compare-and-exchange with padding VS 2019 16.8 20
bits

P0811R3 midpoint(), lerp() VS 2019 16.8 20

P0912R5 Library Support For Coroutines VS 2019 16.8 20

P1001R2 execution::unseq VS 2019 16.8 20

P1032R1 Miscellaneous constexpr VS 2019 16.8 20

P1065R2 constexpr INVOKE VS 2019 16.8 20

P1123R0 Editorial Guidance for merging P0019r8 and P0528r3 VS 2019 16.8 20

P1960R0 NB Comment Changes Reviewed by SG1 VS 2019 16.8 20

P0339R6 polymorphic_allocator<> VS 2019 16.9 20

P0660R10 <stop_token> and jthread VS 2019 16.9 20

P0768R1 Library Support For The Spaceship Comparison Operator <=> VS 2019 16.9 20

P1007R3 assume_aligned() VS 2019 16.9 20

P1020R1 Smart Pointer Creation With Default Initialization VS 2019 16.9 20

P1135R6 The C++20 Synchronization Library VS 2019 16.9 20

P1771R1 Library support for [[nodiscard]] for constructors VS 2019 16.9 20

P0053R7 <syncstream> VS 2019 16.10 20


P0753R2 osyncstream Manipulators
Feature Supported

P0355R7 <chrono> Calendars And Time Zones VS 2019 16.10


20abi

P0408R7 Efficient access To basic_stringbuf's buffer VS 2019 16.10 20

P0466R5 Library support for layout-compatibility and pointer- VS 2019 16.10 20


interconvertibility traits

P0475R1 Guaranteed Copy Elision For Piecewise Construction VS 2019 16.10 20

P0591R4 Utility Functions For Uses-Allocator Construction VS 2019 16.10 20

P0608R3 Improving variant's Converting Constructor/Assignment VS 2019 16.10 20

P0645R10 <format> Text Formatting VS 2019 16.10


20abi

P0784R7 Library support for more constexpr containers VS 2019 16.10 20

P0896R4 <ranges> VS 2019 16.10


20abi

P0980R1 constexpr std::string VS 2019 16.10 20, P

P1004R2 constexpr std::vector VS 2019 16.10 20, P

P1208R6 <source_location> VS 2019 16.10 20

P1502R1 Standard Library Header Units VS 2019 16.10 20

P1614R2 Adding Spaceship <=> To The Library VS 2019 16.10 20

P1285R0 Improving Completeness Requirements For Type Traits N/A

C++20 Standard library features (Defect reports) Supported

P2325R3 Views Should Not Be Required To Be Default Constructible VS 2022 17.0 20abi

P2328R1 join_view should join all views of ranges VS 2022 17.0 20abi

P2367R0 Remove misuses of list-initialization from clause 24 ranges VS 2022 17.0 20abi

P2259R1 Partial LWG issue resolution: repairing Input Range Adaptors and VS 2022 17.0 23
counted_iterator

C++23 Standard library features Supported

P0288R9 move_only_function​ VS 2022 17.2 23

P0323R12 <expected>​​ VS 2022 17.3 23


Feature Supported

P0401R6 Providing Size Feedback In The Allocator Interface​ VS 2022 17.0 23

P0448R4 <spanstream>​ VS 2022 17.1 23

P0627R6 unreachable()​ VS 2022 17.2 23

P0798R8 Monadic Operations For optional​ VS 2022 17.2 23

P0849R8 auto(x): decay-copy In The Language​ VS 2022 17.4 23

P0881R7 <stacktrace>​ VS 2022 17.4 23

P0943R6 Supporting C Atomics In C++​ VS 2022 17.1 23

P1048R1 is_scoped_enum​ VS 2022 17.0 23

P1072R10 basic_string::resize_and_overwrite​ VS 2022 17.1 23

P1132R7 out_ptr(), inout_ptr()​ VS 2022 17.0 23

P1147R1 Printing volatile Pointers​ VS 2022 17.1 23

P1206R7 Conversions From Ranges To Containers​ VS 2022 17.4 23

P1272R4 byteswap()​ VS 2022 17.1 23

P1328R1 constexpr type_info::operator==()​ VS 2022 17.4 23

P1413R3 Deprecate aligned_storage And aligned_union​​ VS 2022 17.3 23

P1425R4 Iterator Pair Constructors For stack And queue​ VS 2022 17.1 23

P1518R2 Stop Overconstraining Allocators In Container Deduction Guides​ VS 2022 17.1 23

P1659R3 ranges::starts_with, ranges::ends_with​ VS 2022 17.1 23

P1679R3 contains() For basic_string/basic_string_view​ VS 2022 17.0 23

P1682R3 to_underlying() For Enumerations​ VS 2022 17.0 23

P1899R3 views::stride​ VS 2022 17.4 23

P1951R1 Default Template Arguments For pair's Forwarding Constructor​ VS 2022 17.0 23

P1989R2 Range Constructor For string_view​ VS 2022 17.0 23

P2077R3 Heterogeneous Erasure Overloads For Associative Containers​ VS 2022 17.2 23

P2136R3 invoke_r()​ VS 2022 17.1 23

P2162R2 Inheriting from std::variant VS 2022 17.0 17


Feature Supported

P2166R1 Prohibit basic_string and basic_string_view from being VS 2022 17.0 23, R
constructed from nullptr

P2186R2 Removed garbage collection support VS 2022 17.0 23, Q

P2251R1 Require span And basic_string_view To Be Trivially Copyable​ VS 2022 17.1 23

P2273R3 constexpr unique_ptr​​ VS 2022 17.3 23

P2291R3 constexpr Integral <charconv>​ VS 2022 17.4 23

P2302R4 ranges::contains, ranges::contains_subrange​ VS 2022 17.4 23

P2321R2 std::zip​ partial in VS 2022


17.5 23

P2322R6 ranges::fold_left, ranges::fold_right, etc.​ VS 2022 17.5 23

P2387R3 Pipe Support For User-Defined Range Adaptors​ VS 2022 17.4 23

P2393R1 Cleaning Up Integer-Class Types​ VS 2022 17.2 23

P2401R0 Conditional noexcept For exchange()​ VS 2022 17.1 23

P2408R5 Ranges Iterators As Inputs To Non-Ranges Algorithms​ VS 2022 17.4 23

P2417R2 More constexpr bitset​ VS 2022 17.4 23

P2419R2 Clarify Handling Of Encodings In Localized Formatting Of chrono VS 2022 17.4 23


Types​

P2438R2 string::substr() &&​ VS 2022 17.4 23

P2440R1 ranges::iota, ranges::shift_left, ranges::shift_right​ VS 2022 17.4 23

P2441R2 views::join_with​ VS 2022 17.4 23

P2442R1 Windowing Range Adaptors: views::chunk, views::slide​​ VS 2022 17.3 23

P2443R1 views::chunk_by​​ VS 2022 17.3 23

P2445R1 forward_like()​ VS 2022 17.4 23

P2446R2 views::as_rvalue​ VS 2022 17.4 23

P2465R3 Standard Library Modules std And std.compat​ no

P2494R2 Relaxing Range Adaptors To Allow Move-Only Types​ VS 2022 17.4 23

P2499R0 string_view Range Constructor Should Be explicit​ VS 2022 17.4 23


Feature Supported

P2508R1 basic_format_string, format_string, wformat_string​ VS 2022 17.5 23

P2517R1 Conditional noexcept For apply()​ VS 2022 17.4 23

P2520R0 move_iterator<T*> Should Be A Random-Access Iterator​​ VS 2022 17.4 23

P2549R1 unexpected<E>::error() VS 2022 17.3 23

A group of papers listed together indicates a Standard feature along with one or more
approved improvements or expansions. These features are implemented together.

C Standard library features


ノ Expand table

Feature Supported

C99 Standard library features Supported

Alternative spellings macros <iso646.h> VS 2015

Wide character support <wchar.h> and <wctype.h> VS 2015

Complex support in <complex.h> Partial in VS 2015 K

Type generic math functions <tgmath.h> VS 2019 16.8 2104

Additional floating point characteristics <float.h> VS 2015

Hexadecimal float printf specifiers %A , %a VS 2015

Extended integers types <inttypes.h> , <stdint.h> VS 2015

vscanf family in <stdio.h> and <wchar.h> VS 2015

New math functions in <math.h> VS 2015

Treatment of math library error conditions ( math_errhandling ) VS 2015

Floating point environment access <fenv.h> VS 2015

%lf conversion specifier for printf VS 2015

snprintf family of functions in <stdio.h> VS 2015

boolean type in <stdbool.h> VS 2015


Feature Supported

va_copy macro VS 2015

Additional strftime conversion specifiers Partial in VS 2015 L

C11 Standard library features Supported

Alignment specifiers <stdalign.h> VS 2019 16.8 C11, 2104

aligned_alloc No M

No return specifiers <stdnoreturn.h> VS 2019 16.8 C11, 2104

Threading support <threads.h> yes

Atomic support <stdatomic.h> experimental

char16_t , char32_t <uchar.h> VS 2019 16.8 C11

gets() removed VS 2019 16.8 C11, N

gets_s() VS 2019 16.8 C11

Bounds-checking interfaces ( *_s APIs) Partial in VS 2015 C11, O

fopen "x" option VS 2019 16.8 C11

Static assertions VS 2019 16.8 C11, 2104

quick_exit VS 2019 16.8 C11

<complex.h> macros VS 2019 16.8 C11

floating point characteristics <float.h> VS 2019 16.8 C11

C11 threads <threads.h> VS 2022 17.8 C11

Supported values
No Not yet implemented.
Partial The implementation is incomplete. For more information, see the Notes section.
VS 2010 Supported in Visual Studio 2010.
VS 2013 Supported in Visual Studio 2013.
VS 2015 Supported in Visual Studio 2015 (RTW).
VS 2015.2 and VS 2015.3 indicate features that are supported in Visual Studio 2015
Update 2 and Visual Studio 2015 Update 3, respectively.
VS 2017 15.0 Supported in Visual Studio 2017 version 15.0 (RTW).
VS 2017 15.3 Supported in Visual Studio 2017 version 15.3.
VS 2017 15.5 Supported in Visual Studio 2017 version 15.5.
VS 2017 15.7 Supported in Visual Studio 2017 version 15.7.
VS 2019 16.0 Supported in Visual Studio 2019 version 16.0 (RTW).
VS 2019 16.1 Supported in Visual Studio 2019 version 16.1.
VS 2019 16.2 Supported in Visual Studio 2019 version 16.2.
VS 2019 16.3 Supported in Visual Studio 2019 version 16.3.
VS 2019 16.4 Supported in Visual Studio 2019 version 16.4.
VS 2019 16.5 Supported in Visual Studio 2019 version 16.5.
VS 2019 16.6 Supported in Visual Studio 2019 version 16.6.
VS 2019 16.7 Supported in Visual Studio 2019 version 16.7.
VS 2019 16.8 Supported in Visual Studio 2019 version 16.8.
VS 2019 16.9 Supported in Visual Studio 2019 version 16.9.
VS 2019 16.10 Supported in Visual Studio 2019 version 16.10.
VS 2022 17.0 Supported in Visual Studio 2022 version 17.0.
VS 2022 17.1 Supported in Visual Studio 2022 version 17.1.
VS 2022 17.2 Supported in Visual Studio 2022 version 17.2.
VS 2022 17.3 Supported in Visual Studio 2022 version 17.3.
VS 2022 17.4 Supported in Visual Studio 2022 version 17.4.
VS 2022 17.5 Supported in Visual Studio 2022 version 17.5.

Notes
A In /std:c++14 mode, dynamic exception specifications remain unimplemented, and
throw() is still treated as a synonym for __declspec(nothrow) . In C++17, dynamic

exception specifications were mostly removed by P0003R5, except for one vestige:
throw() is deprecated and required to behave as a synonym for noexcept . In /std:c++17

mode, MSVC now conforms to the Standard by giving throw() the same behavior as
noexcept , that is, enforcement via termination.

The compiler option /Zc:noexceptTypes requests the old behavior of


__declspec(nothrow) . It's likely that throw() will be removed in a future version of C++.

To help with migrating code in response to these changes in the Standard and the
Microsoft implementation, new compiler warnings for exception specification issues are
added under /std:c++17 and /permissive-.

B Supported in /permissive- mode in Visual Studio 2017 version 15.7. For more
information, see Two-phase name lookup support comes to MSVC .

C In Visual Studio 2019 version 16.6 and later versions, the compiler fully implements
the standard C99 preprocessor via the /Zc:preprocessor option. (In Visual Studio 2017
versions 15.8 through 16.5, the compiler supports the standard C99 preprocessor via the
/experimental:preprocessor compiler option.) This option is on by default when the
compiler option /std:c11 or /std:c17 is specified.

D Supported under /std:c++14 with a suppressible warning, C4984.

E The implementation is sufficient to support the C++20 Standard Library. A complete


implementation requires a binary breaking change.

F Features removed when the /std:c++17 or later compiler option is specified. To re-
enable these features (to ease the transition to newer language modes), use these
macros: _HAS_AUTO_PTR_ETC , _HAS_FUNCTION_ALLOCATOR_SUPPORT ,
_HAS_OLD_IOSTREAMS_MEMBERS , and _HAS_UNEXPECTED .

G C++17's parallel algorithms library is complete. Complete doesn't mean that every
algorithm is parallelized in every case. The most important algorithms have been
parallelized. Execution policy signatures are provided even where the implementation
doesn't parallelize algorithms. The central internal header, <yvals_core.h> , contains the
following "Parallel Algorithms Notes": C++ allows an implementation to implement
parallel algorithms as calls to the serial algorithms. This implementation parallelizes
several common algorithm calls, but not all.

The following algorithms are parallelized:

adjacent_difference , adjacent_find , all_of , any_of , count , count_if , equal ,


exclusive_scan , find , find_end , find_first_of , find_if , find_if_not , for_each ,

for_each_n , inclusive_scan , is_heap , is_heap_until , is_partitioned , is_sorted ,

is_sorted_until , mismatch , none_of , partition , reduce , remove , remove_if ,


replace , replace_if , search , search_n , set_difference , set_intersection , sort ,

stable_sort , transform , transform_exclusive_scan , transform_inclusive_scan ,


transform_reduce

These algorithms aren't presently parallelized:

These algorithms show no noticeable parallelism performance improvement on


target hardware. All algorithms that merely copy or permute elements with no
branches are typically memory bandwidth limited:
copy , copy_n , fill , fill_n , move , reverse , reverse_copy , rotate , rotate_copy ,

shift_left , shift_right , swap_ranges

Confusion over user parallelism requirements exists for these algorithms, which are
likely in the above category anyway:
generate , generate_n

Effective parallelism of these algorithms might be infeasible:


partial_sort , partial_sort_copy

These algorithms haven't been evaluated yet. The library might implement
parallelism in a future release:
copy_if , includes , inplace_merge , lexicographical_compare , max_element ,

merge , min_element , minmax_element , nth_element , partition_copy ,

remove_copy , remove_copy_if , replace_copy , replace_copy_if ,


set_symmetric_difference , set_union , stable_partition , unique , unique_copy

H This is a wholly new implementation, incompatible with the previous


std::experimental version, made necessary by symlink support, bug fixes, and changes

in standard-required behavior. Currently, <filesystem> provides both the new


std::filesystem and the previous std::experimental::filesystem . The
<experimental/filesystem> header provides only the old experimental implementation.

Expect removal of the experimental implementation in the next ABI-breaking release of


the libraries.

I Supported by a compiler intrinsic.

J std::byte is enabled by /std:c++17 or later, but because it can conflict with the
Windows SDK headers in some cases, it has a fine-grained opt-out macro. To disable it,
define _HAS_STD_BYTE as 0 .

K MSVC doesn't support the _Complex keyword or native complex types. The Universal
CRT <complex.h> uses implementation-specific macros to achieve the same effect. For
more information, see C complex math support.

L The Universal CRT doesn't implement the strftime E and O alternative conversion
modifiers. These modifiers are ignored (for example, %Oe behaves the same as %e ). The
modifiers aren't supported by the underlying locale APIs.

M The Universal CRT doesn't implement C11 aligned_alloc , but does provide
_aligned_malloc and _aligned_free. Because the Windows operating system doesn't
support aligned allocations, this function is unlikely to be implemented.

N The declaration is removed, but the export for the function remains for backward
compatibility.

O Certain bounds-checking functions are unimplemented, or have different signatures,


or aren't part of the C11 or C17 standard. These functions are unimplemented:
abort_handler_s , ignore_handler_s , memset_s , set_constraint_handler_s , snprintf_s ,

snwprintf_s , strerrorlen_s , vsnwprintf_s . These functions have different signatures:


gmtime_s , localtime_s , qsort_s , strtok_s , vsnprintf_s , wcstok_s . These functions

don't appear in the standard: clearerr_s , fread_s .

P Support was added in Visual Studio 2019 version 16.10. Support for Clang was added
in Visual Studio 2022 version 17.0.

Q This removes declare_reachable , undeclare_reachable , declare_no_pointers ,


undeclare_no_pointers , get_pointer_safety . Previously, these functions had no effect.

R This is a common source-breaking change. However, code that previously had


undefined behavior at runtime is now rejected with compiler errors.

S Input range adaptors and counted_iterator are implemented in VS 2022 17.0. A


future update to Visual Studio 2019 version 16.11 is planned to incorporate these
changes.

T <stdatomic.h> is currently supported when compiled as C++ ( /std:c++latest ). It isn't


yet supported when compiled as C ( /std:c11 and /std:c17 )

14 These C++17 and C++20 features are always enabled, even when /std:c++14 (the
default) is specified. The reason is either because the feature was implemented before
the introduction of the /std options, or because conditional implementation was
undesirably complex.

17 These features are enabled by the /std:c++17 or later compiler option.

20 In versions through Visual Studio 2019 version 16.10, these features are enabled by
the /std:c++latest compiler option. Visual Studio 2019 version 16.11 added the
/std:c++20 compiler option to enable these features.

20abi Because of ongoing post-release work on the C++20 standard, <format> , the
formatting parts of <chrono> (which rely on <format> ), and the range factories and
range adaptors from <ranges> (everything that needs the view concept) are only
available under /std:c++latest . Expect these features under /std:c++20 after
agreement is reached with WG21 that no further ABI-breaking changes are necessary.
The remaining parts of <chrono> and the algorithms that apply to ranges are enabled
under the /std:c++20 compiler option in Visual Studio 2019 version 16.11 and later
versions.

23 In Visual Studio 2022 version 17.0 and up, these features are enabled by the
/std:c++latest compiler option.

C11 Compiler support for C11 and C17 requires Visual Studio 2019 version 16.8 or
higher. Except as noted, C11 and C17 library support requires Windows SDK build
10.0.20211.0 or higher. For more information on how to install support for C11 and C17,
see Install C11 and C17 support in Visual Studio.

DR These features are enabled in all C++ /std compiler option modes. The C++
Standard committee adopted this change as a retroactive Defect Report to C++11 and
all later versions.

2104 C11 library support for this feature requires Windows SDK build 10.0.20348.0
(version 2104) or higher.

See also
C++ Language Reference
C++ Standard Library
C++ conformance improvements in Visual Studio
What's New for Visual C++ in Visual Studio
Visual C++ change history 2003 through 2015
Visual C++ What's New 2003 through 2015
C++ team blog

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Supported platforms (Visual C++)
Article • 11/11/2021

Apps built by using Visual Studio can be targeted to various platforms.

Visual Studio target OS and architecture


support
ノ Expand table

Operating System x86 x64 ARM ARM64a

Windows XP b X X

Windows Vista X X

Windows 7 X X

Windows 8 X X X

Windows 8.1 X X X

Windows 10 X X X X

Windows 11 X X X X

Windows Server 2003 b X X

Windows Server 2008 R2 X X

Windows Server 2012 R2 X X

Windows Server 2016 X X

Windows Server 2019 X X

Windows Server 2022 X X

Android c X X X X

iOS c X X X X

Linux d X X X X

a ARM64 support is available in Visual Studio 2017 and later.


b You can use the Windows XP platform toolsets included in Visual Studio 2017, Visual
Studio 2015, Visual Studio 2013, and Visual Studio 2012 Update 1 to build Windows XP
and Windows Server 2003 projects. For information on how to use these platform
toolsets, see Configuring Programs for Windows XP. For more information on changing
the platform toolset, see How to: Modify the Target Framework and Platform Toolset.

c You can install the Mobile development with C++ workload in the installer for Visual
Studio 2017 and later. In Visual Studio 2015 setup, choose the optional Visual C++ for
Cross Platform Mobile Development component to target iOS or Android platforms.
For instructions, see Install Visual C++ for Cross-Platform Mobile Development. To build
iOS code, you must have a Mac computer and meet other requirements. For a list of
prerequisites and installation instructions, see Install And Configure Tools to Build using
iOS. You can build x86 or ARM code to match the target hardware. Use x86
configurations to build for some Android devices. Use ARM configurations to build for
iOS devices and most Android devices.

d
You can install the Linux development with C++ workload in the installer for Visual
Studio 2017 and later to target Linux platforms. For instructions, see Download, install,
and setup the Linux Workload. This toolset compiles your executable on the target
machine, so you can build for any supported architecture.

For information about how to set the target platform configuration, see How to:
Configure Visual C++ projects to target 64-bit, x64 platforms.

See also
Visual C++ tools and features in Visual Studio editions
Getting Started
Microsoft Visual C++ compiler
versioning
Article • 02/16/2024

The Microsoft Visual C++ compiler version consists of four fields:

M - major version (two digits)


N - minor version (two digits)
B - build version (five digits)
R - revision version

Microsoft-specific compiler macros encode these fields as follows:

_MSC_VER = MMNN

_MSC_FULL_VER = MMNNBBBBB
_MSC_BUILD = R

For example, the compiler version for Visual Studio 2022 version 17.9.0 is 19.39.33519:

The major version is 19


The minor version is 39
The build version is 33519
The revision version is 0

The macros reflect these values like this:

_MSC_VER = 1939

_MSC_FULL_VER = 193933519

_MSC_BUILD (the revision) is 0.

7 Note

Visual Studio 2019 16.8 and 16.9 share the same major and minor versions, and so
have the same value for _MSC_VER . As do Visual Studio 2019 16.10 and 16.11. To
distinguish them, use _MSC_FULL_VER as described in Service releases starting with
Visual Studio 2017.

A brief history of Visual C++ compiler


versioning
Visual Studio 6.0 through Visual Studio 2015 (14.0)
For major releases, _MSC_VER increases by 100. _MSC_FULL_VER increases by
10,000,000.

For minor releases, _MSC_VER increases by 10. _MSC_FULL_VER increases by


1,000,000.

7 Note

Visual Studio .NET 2003 was considered a minor release.

Visual Studio 2017 and later


For major releases, the minor version increases by 10.
For minor releases, the minor version increases by 1 starting with Visual Studio
2017 version 15.3.

Service releases starting with Visual Studio 2017


Servicing releases can be distinguished by _MSC_FULL_VER . The build field (the BBBBB in
the MMNNBBBBB version number) typically increases by 1.

For example, two cases where _MSC_FULL_VER is useful is to distinguish Visual Studio
2019 16.8 from 16.9, and Visual Studio 2019 16.10 from 16.11. That's because those
versions share the same major and minor versions, and so have the same value for
_MSC_VER .

To distinguish these versions, use _MSC_FULL_VER .


The minimum value of _MSC_FULL_VER for Visual Studio 2019 16.8 is 192829333.
The minimum value of _MSC_FULL_VER for Visual Studio 2019 16.9 is 192829910.

Version macros
Recall that the version number consists of four fields:

M - major version (two digits)


N - minor version (two digits)
B - build version (five digits)
R - revision version
_MSC_VER distinguishes between major and minor releases. It has the form: MMNN.

_MSC_FULL_VER represents the major, minor, and build version of the compiler. It has
the form: MMNNBBBBB. Use it to distinguish between different versions of the compiler,
including servicing releases. See Service releases starting with Visual Studio 2017 for
more information about Visual Studio 2019 16.8, 16.9, 16.10 and 16.11.

_MSC_BUILD represents the build version of the compiler. It has the form: R. Use it to
distinguish between servicing releases.

When the major version changed between Visual Studio 2013 and Visual Studio 2015,
_MSC_VER reflected the change by going from 1800 to 1900.

An example of a minor change is from Visual Studio 2022 17.1 to Visual Studio 2022
17.2. In that case, _MSC_VER changed from 1931 to 1932.

The following table lists the Visual C++ compiler _MSC_VER for each Visual Studio
release:

ノ Expand table

Visual Studio version _MSC_VER

Visual Studio 6.0 1200

Visual Studio .NET 2002 (7.0) 1300

Visual Studio .NET 2003 (7.1) 1310

Visual Studio 2005 (8.0) 1400

Visual Studio 2008 (9.0) 1500

Visual Studio 2010 (10.0) 1600

Visual Studio 2012 (11.0) 1700

Visual Studio 2013 (12.0) 1800

Visual Studio 2015 (14.0) 1900

Visual Studio 2017 RTW (15.0) 1910

Visual Studio 2017 version 15.3 1911

Visual Studio 2017 version 15.5 1912

Visual Studio 2017 version 15.6 1913


Visual Studio version _MSC_VER

Visual Studio 2017 version 15.7 1914

Visual Studio 2017 version 15.8 1915

Visual Studio 2017 version 15.9 1916

Visual Studio 2019 RTW 16.0 1920

Visual Studio 2019 version 16.1 1921

Visual Studio 2019 version 16.2 1922

Visual Studio 2019 version 16.3 1923

Visual Studio 2019 version 16.4 1924

Visual Studio 2019 version 16.5 1925

Visual Studio 2019 version 16.6 1926

Visual Studio 2019 version 16.7 1927

Visual Studio 2019 version 16.8, 16.9 a 1928

Visual Studio 2019 version 16.10, 16.11 b 1929

Visual Studio 2022 RTW 17.0 1930

Visual Studio 2022 version 17.1 1931

Visual Studio 2022 version 17.2 1932

Visual Studio 2022 version 17.3 1933

Visual Studio 2022 version 17.4 1934

Visual Studio 2022 version 17.5 1935

Visual Studio 2022 version 17.6 1936

Visual Studio 2022 version 17.7 1937

Visual Studio 2022 version 17.8 1938

Visual Studio 2022 version 17.9 1939

Visual Studio 2022 version 17.10 1940

a
Visual Studio 2019 16.8 and 16.9 share the same major and minor versions (and so
have the same value for _MSC_VER ). To distinguish them, use _MSC_FULL_VER . The
minimum value of _MSC_FULL_VER for Visual Studio 2019 16.8 is 192829333. The
minimum value of _MSC_FULL_VER for Visual Studio 2019 16.9 is 192829910.

b
Visual Studio 2019 16.10 and 16.11 share the same major and minor versions (and so
have the same value for _MSC_VER ). To distinguish them, use _MSC_FULL_VER . The
minimum value of _MSC_FULL_VER for Visual Studio 2019 16.10 is 192929917. The
minimum value of _MSC_FULL_VER for Visual Studio 2019 16.11 is 192930129.

See also
_MSC_VER
Visual C++ compiler version blog post
C++ Tools and Features in Visual Studio
Editions
Article • 12/01/2021

The following C++ features are available in Visual Studio. Unless stated otherwise, all
features are available in all editions: Visual Studio Community, Visual Studio
Professional, and Visual Studio Enterprise. Some features require specific workloads or
optional components, which you can install with the Visual Studio Installer.

Platforms
Windows Desktop
Universal Windows Platform ((tablet, PC, Xbox, IoT, and HoloLens))
Linux
Android
iOS

Compilers
MSVC 32-bit compiler for x86, x64, ARM, and ARM64
MSVC 64-bit compiler for x86, x64, ARM, and ARM64
GCC cross-compiler for ARM
Clang/LLVM
On Windows, Clang/LLVM 12.0, targeting x86 or x64 (CMake support only).
On Linux, any Clang/LLVM installation supported by the distro.

C++ Workloads
Visual Studio includes the following workloads for C++ development. You can install any
or all of these, along with other workloads such as .NET Desktop Development, Python
Development, Azure Development, Visual Studio Extension Development, and others.

Desktop development with C++


Included:

C++ core desktop features


Optional Components:

MSVC v143 - VS 2022 C++ x64/x86 build tools (latest)


Windows 10 SDK (latest for this Visual Studio version)
Just-In-Time debugger
C++ profiling tools
C++ CMake tools for Windows
C++ ATL for v143 build tools (x86 & x64)
Test Adapter for Boost.Test
Test Adapter for Google Test
Live Share
IntelliCode
C++ AddressSanitizer
IntelliTrace (Enterprise only)
MSVC v143 - VS 2022 C++ ARM64 build tools (latest)
C++ MFC for latest v143 build tools (x86 & x64)
C++/CLI support for v143 build tools (latest)
C++ Modules for v143 build tools (x64/x86 – experimental)
C++ Clang tools for Windows (12.0.0 - x64/x86)
JavaScript diagnostics
IncrediBuild - Build Acceleration
Windows 11 SDK
Windows 10 SDK (other versions)
MSVC v142 - VS 2019 C++ x64/x86 build tools (v14.29)
MSVC v141 - VS 2017 C++ x64/x86 build tools (v14.16)
MSVC v140 - VS 2015 C++ build tools (v14.00)

Linux development with C++


Included:

C++ core features


C++ for Linux Development

Optional Components:

C++ CMake tools for Linux


IntelliCode
Embedded and IoT development tools

Universal Windows Platform development


Included:

Blend for Visual Studio


.NET Native and .NET Standard
NuGet package manager
Universal Windows Platform tools
Windows 10 SDK (latest for this Visual Studio version)

Optional Components:

IntelliCode
IntelliTrace (Enterprise only)
USB Device Connectivity
C++ (v143) Universal Windows Platform tools
C++ (v142) Universal Windows Platform tools
C++ (v141) Universal Windows Platform tools
Graphics debugger and GPU profiler for DirectX
Windows 11 SDK
Windows 10 SDK (other versions)
Architecture and analysis tools

C++ Game Development


Included:

C++ core features


Windows Universal C Runtime
C++ 2019 Redistributable Update
MSVC v143 - VS 2022 C++ x64/x86 build tools (latest)

Optional Components:

C++ profiling tools


C++ AddressSanitizer
Windows 10 SDK (latest for this Visual Studio version)
IntelliCode
IntelliTrace (Enterprise only)
Windows 11 SDK
Windows 10 SDK (other versions)
IncrediBuild - Build Acceleration
Cocos
Unreal Engine installer
Android IDE support for Unreal engine
Mobile development with C++
Included:

C++ core features


Android SDK setup (API level 25) (local install for Mobile development with C++)

Optional Components:

Android NDK (R21E)


Apache Ant (1.9.3)
C++ Android development tools
IntelliCode
Intel Hardware Accelerated Execution Manager (HAXM) (local install)
C++ iOS development tools
IncrediBuild - Build Acceleration

Individual components
You can install these components independently from any workload.

JavaScript diagnostics
Live Share
C++ Universal Windows Platform runtime for v142 build tools
ClickOnce Publishing
Microsoft Visual Studio Installer Projects
Windows SDK

Libraries and Headers


Windows headers and libraries
Windows Universal C Runtime (CRT)
C++ Standard Library
ATL
MFC
.NET Framework class library
C++ Support Library for .NET
OpenMP 2.0
Over 900 open-source libraries via vcpkg catalog

Build and Project Systems


CMake
Any build system via Open Folder
Command line builds (msbuild.exe)
Native Multi-targeting
Managed Multi-targeting
Parallel Builds
Build Customizations
Property Pages Extensibility

Project Templates
The following project templates are available depending on which workloads you have
installed.

Windows Desktop:

Empty Project
Console App
Windows Desktop Wizard
Windows Desktop Application
Shared Items Project
MFC App
Dynamic Link Library
CLR Empty Project
CLR Console App
Static Library
CMake Project
ATL Project
MFC Dynamic Link Library
CLR Class Library
Makefile Project (Windows)
MFC ActiveXControl
Native Unit Test Project
Google Test

Universal Windows Platform (C++/CX):

Blank App
DirectX 11 and XAML App
DirectX 11 App
DirectX 12 App
Unit Test App
DLL
Windows Runtime Component
Static Library
Windows Application Packaging Project

Linux:

Console App (Linux)


Empty Project (Linux)
Raspberry Pi Blink
Makefile Project (Linux)

Tools
Incremental Linker (Link.exe)
Microsoft Makefile Utility (Nmake.exe)
Lib Generator (Lib.exe)
Windows Resource Compiler (Rc.exe)
Windows Resource to Object Converter (CvtRes.exe)
Browse Information Maintenance Utility (BscMake.exe)
C++ Name Undecorator (Undname.exe)
COFF/PE Dumper (Dumpbin.exe)
COFF/PE Editor (Editbin.exe)
MASM (Ml.exe)
Spy++
ErrLook
AtlTrace
Inference Rules
Profile Guided Optimizations

Debugging Features
Native Debugging
natvis (native type visualization)
Graphics Debugging
Managed Debugging
GPU usage
Memory usage
Remote Debugging
SQL Debugging
Static Code Analysis
Designers and Editors
XAML Designer
CSS Style Designer/Editor
HTML Designer/Editor
XML Editor
Source Code Editor
Productivity Features: Refactoring, EDG IntelliSense engine, C++ Code Formatting
Windows Forms Designer
Data Designer
Native Resource Editor (.rc files)
Resource Editors
Model editor
Shader designer
Live Dependency Validation (Enterprise Only)
Architectural Layer Diagrams (Enterprise Only)
Architecture Validation (Enterprise Only)
Code Clone (Enterprise Only)

Data Features
Data Designer
Data Objects
Web Services
Server Explorer

Automation and Extensibility


Extensibility Object Models
Code Model
Project Model
Resource Editor Model
Wizard Model
Debugger Object Model

Application Lifecycle Management Tools


Unit Testing (Microsoft Native C++, Boost.Test, Google Test, CTest)
Code map and dependency graphs (Professional and Enterprise)
Code coverage (Enterprise Only)
Manual testing (Enterprise only)
Exploratory testing (Enterprise only)
Test case management (Enterprise only)
Code map debugger integration (Enterprise only)
Live Unit Testing (Enterprise only)
IntelliTrace (Enterprise only)
IntelliTest (Enterprise only)
Microsoft Fakes (Unit Test Isolation) (Enterprise only)
Code Coverage (Enterprise only)

See also
Install Visual Studio
What's New in Visual Studio
C++ project types in Visual Studio
Install C11 and C17 support in Visual
Studio
Article • 10/29/2021

Support for C11 and C17 standards is available in Visual Studio 2019 version 16.8 and
later. Support requires an updated Universal C Runtime (UCRT) and Windows SDK
version to work properly with the conforming preprocessor (/Zc:preprocessor).

Windows SDK releases correspond with Windows OS releases. C11 and C17 support
requires Windows SDK 10.0.20348.0 (version 2104) or later. The Windows SDK is an
installable option in the Individual Components tab in the Visual Studio Installer. You
can follow these steps to set up the latest SDK and build C11 or C17 code in Visual
Studio or at the command line.

Prerequisites
Visual Studio 2019 version 16.8 or later and Windows SDK 10.0.20348.0 (version 2104) or
later installed and running on your computer. We recommend you use the latest version
available for the best support.

If Visual Studio isn't installed yet, see Install C++ support in Visual Studio for
installation instructions. In the install, include the Desktop development with C++
workload. Then, open the Individual Components tab. Select Windows 10 SDK
(10.0.20348.0) or later, or the latest Windows 11 SDK.

If Visual Studio is already installed, but you don't have the required Windows SDK,
open the Visual Studio Installer. Choose Modify next to your version of Visual
Studio to install the selected components. Open the Individual Components tab.
Select Windows 10 SDK (10.0.20348.0) or later, or the latest Windows 11 SDK.
Choose Modify to install the selected components.

When installation completes, open Visual Studio.

Configure C11 or C17 mode in Visual Studio


In Visual Studio, open a new or existing C project, then open your project's Property
Pages dialog.

Set the project to use the Windows SDK you just installed. On the Configuration
Properties > General page, set the Windows SDK Version property either to 10.0 (latest
installed version), or to the specific SDK version you installed.

You'll also see a C-specific option: C Language Standard. Set this property to ISO C11
Standard ( /std:c11 ) or ISO C17 (2018) Standard ( /std:c17 ).

The C++ Language Standard property is used when the language is C++. It's the default
when the file extension is .cpp . The C Language Standard property version is used when
the language is C. It's the default when the file extension is .c . To build using C11 or
C17, put your source code in a .c file, or set the code to compile as C. You can set this
property for your project on the Configuration Properties > C/C++ > Advanced page.
Set the Compile As property to Compile as C code (/TC).

Congratulations, you've set up everything you need to build C11 and C17 code in Visual
Studio!

See also
/std (Specify language standard version)
Visual Studio C++ Samples
Article • 08/30/2022

Samples for Visual Studio C++ are available on the web. Microsoft has produced many
C++ samples that demonstrate different functionalities across multiple technologies.
Here are a few of the places to find additional samples:

C++ code samples

Windows samples on GitHub

Windows Dev Center code samples

ADO code samples

Windows Hardware development samples

Archived C++ samples on GitHub


Visual Studio included C++ sample code in previous versions. The sample code was
either installed with Visual Studio, or was available as a separate download. Many
articles in our documentation refer to these samples. They don't get installed by Visual
Studio anymore. Instead, a repository is available on GitHub. The tables below have
descriptions for each sample, and links to the sample's directory in the repository.

) Important

This sample code is intended to illustrate a concept, and it shows only the code
that is relevant to that concept. It may not meet the security requirements for a
specific environment, and it should not be used exactly as shown. We recommend
that you add security and error-handling code to make your projects more secure
and robust. Microsoft provides this sample code "AS IS" with no warranties.

ATL samples

ATL samples - Advanced

ノ Expand table
Sample name Description

ActiveDoc Demonstrates how to implement an Active Document Server.

Async Downloads data asynchronously from a URL.

ATLButton Creates a button that displays itself with three different bitmaps depending on
its state.

ATLDuck Demonstrates using connection points with ATL controls.

ATLSecurity Shows how to use the ATL security classes to examine security settings.

ATLTraceTool Displays the output generated by the ATLTRACE2 macro.

Connect Illustrates the implementation and use of connection points (the


IConnectionPointContainer and IConnectionPoint interfaces) in a multithreaded
environment.

CThreadPool Shows how to use a thread pool in an application and how implementing a
thread pool can improve the application's performance.

DCOM Demonstrates how to call a COM object (implemented in a Windows service)


from multiple clients, running on different machines.

MFCATL Illustrates how ATL COM objects can be used in an MFC server EXE.

ATL samples - Controls

ノ Expand table

Sample Description
name

ATLFire Demonstrates how to build a windowed control using ATL.

CDInfo Plays CD audio tracks and displays information about the tracks in tooltips and a
pie chart display.

Circ Creates a control that demonstrates property pages and draws a circle.

Polygon Builds a control that implements custom properties, events, property pages, and
object safety.

SubEdit Creates a superclassed Windows control.

ATL samples - General


ノ Expand table

Sample name Description

ATLCollections Demonstrates the use of ICollectionOnSTLImpl and CComEnumOnSTL , and the


implementation of custom copy policy classes.

ATLCon Demonstrates a simple control container.

ATLSafeArray Shows how to create and maintain SAFEARRAY s using CComSafeArray ; also how
to pass SAFEARRAY s from a component to script.

AutoThread Demonstrates using CComAutoThreadModule Class.

Beeper Implements a tear-off interface of a collection/enumeration of BSTR s.

CircColl Implements a collection/enumeration of objects using ATL and the Standard


C++ Library.

COMMap Demonstrates COM interface map entry macros with compiler COM support.

CustomString Shows how to use a custom memory allocator for CStringT to improve
performance in a multithreaded application.

DispSink Demonstrates using a connection point on dispatch interfaces.

ATL samples - OLEDB - Consumer

ノ Expand table

Sample name Description

CatDB Displays the schema information, such as tables and columns, of OLE DB
providers.

DBViewer Demonstrates a mid-level application that relies on the CManualAccessor


class to take full control of data bindings for your applications.

DynamicConsumer Demonstrates using dynamic accessor and schema rowset classes to read
metadata from a database.

MultiRead Reads through a table in a database using multiple threads.

ATL samples - OLEDB - Provider

ノ Expand table
Sample name Description

AdvancedPV Implements an updatable OLE DB Provider. Demonstrates some advanced


techniques.

UpdatePV Implements an updatable (read/write) OLE DB provider.

CLR and language samples - Windows Forms


ノ Expand table

Sample name Description

BirthdayPicker Shows how the .NET Framework resource mechanism can be used in C++
applications. It also demonstrates some common Window Forms
components.

Calculator Implements a simple pocket calculator using C++ and the .NET
Framework Windows Forms classes.

Scribble (using MFC) An MFC implementation of the Scribble sample, updated and extended to
include new .NET functionality.

Scribble (Windows A Windows Forms implementation of the Scribble sample, updated and
Forms) extended to include new .NET functionality.

STLCLR Demonstrates some of the capabilities available when using the STL/CLR
Library.

COM events samples


ノ Expand table

Sample name Description

COMEvents Demonstrates event handling using COM.

ComTypeLibfor7 samples
ノ Expand table
Sample Description
name

ACDual Adds dual interfaces to an Automation application.

ADOSamp Implements a three-tier client/server application.

AllInOne Implements a server using ATL, exposing STL collections, and controlled by
compiler COM support in an MFC application.

COMMap Demonstrates COM interface map entry macros with compiler COM support.

Connect Illustrates the use and implementation of connection points (the


IConnectionPointContainer and IConnectionPoint interfaces) in a multithreaded
environment.

DCOM Demonstrates how to call a COM object (implemented in a Windows service) from
multiple clients, running on different computers.

FreeThrd Demonstrates a multithreaded client and free-threaded server with compiler COM
support.

InProc Demonstrates an in-process Automation server application with compiler COM


support.

Labrador Implements an EXE server that doesn't have any user interface.

MFCCalc Demonstrates an Automation server application with compiler COM support.

Compiler samples

Compiler samples - General

ノ Expand table

Sample Description
name

ccWrapper Demonstrates how to map C/C++ compiler flags from other compilers to the
Visual C++ compiler (cl.exe).

Compiler samples - MASM

ノ Expand table
Sample name Description

EuclidStep1 A pure C project that demonstrates Euclid's algorithm for finding the greatest
common divisor.

EuclidStep2 An extension of EuclidStep1 that is a mixed C and MASM project. The core of
Euclid's algorithm is moved from the .c file to an .asm file, with the .c file
calling into the .asm file.

PrimesStep1 A pure C project that demonstrates the Sieve of Eratosthenes to find prime
numbers.

PrimesStep2 An extension of PrimesStep1 that is a mixed C and MASM project that moves the
core algorithm to the .asm file.

PrimesStep3 An extension of PrimesStep2 that adds a separate C header file and an .asm
include file to declare the extern function and global data structure.

CRT samples
ノ Expand table

Sample Description
name

CPUID Determines the capabilities of the CPU being run.

CRT_Dbg1 Illustrates the basic debugging features of the C run-time libraries.

CRT_Dbg2 Demonstrates the C run-time debugging hook functions.

DFACObjs Shows how to use the _CrtDoForAllClientObjects C run-time function to iterate


through a linked list of client objects.

Report Illustrates the C run-time debugging report functions.

RTC Demonstrates the run-time error checks feature.

SecureCRT This sample demonstrates how to upgrade code that used deprecated CRT
functions to increase code security.

Debugging samples
ノ Expand table
Sample Description
name

EEAddIn Uses the Expression Evaluator Add-In API to extend the native debugger
expression evaluator.

Fusion samples
ノ Expand table

Sample Description
name

TraceMan Provides information about application-dependent assemblies, and the


assemblies' state in the native fusion cache, in human readable form.

Hilo sample
ノ Expand table

Sample Description
name

Hilo Hilo is a series of articles and sample applications. They demonstrate the power of
Windows 7, Visual Studio and C++ to build high performance, responsive client
applications. Hilo provides both source code and guidance that will help you design
and develop compelling, touch-enabled Windows applications of your own.

This sample has been updated for Visual Studio 2013. It includes a hot fix to the
AsyncLoaderMemoryManager.cpp file (in lines 36 and 37), which addresses a common
crash issue.

International samples
ノ Expand table

Sample Description
name

IME Demonstrates how to control the Input Method Editor mode and how to
implement IME level 3.
Sample Description
name

SatDLL Demonstrates a recommended way to implement multilingual resources in a


Win32 application.

UniRes Demonstrates the use of Unicode resource files.

Language samples - General


ノ Expand table

Sample Description
name

Data Demonstrates simple access to a SQL Database.

MEDriver Illustrates the use of COM events (fired from an unmanaged COM server) through
a .NET Framework wrapper, automatically generated from the COM server's type
library.

Nile Demonstrates ASP.NET Web Forms and ASP.NET Web Services.

QStat Shows how to create a DLL that wraps access to a COM object and exposes its
functionality to .NET Framework clients.

Scribble Demonstrates how to develop a Windows Forms MDI application using C++/CLI
and the .NET Framework classes.

TilePuzzle Demonstrates interoperability between managed components (written with C++


and C#) and native components (written with C++ using COM attributes).

MFC samples

MFC samples - Advanced

ノ Expand table

Sample name Description

Collect Demonstrates MFC C++ template-based collection classes and standard


prebuilt collection classes.

Cube OpenGL application using MFC device contexts along with OpenGL's resource
contexts.
Sample name Description

DLLHusk Sharing the DLL version of the Foundation class library with an application and
custom DLL.

DLLScreenCap A regular DLL that can be statically or dynamically linked to the Microsoft
Foundation Class Library.

MTGDI Demonstration of sharing GDI resources among multiple threads using the
framework's single document interface (SDI) support for documents and views.

MTMDI Multithread illustration, where user-interface events are processed in a


separate user-interface thread.

MTRecalc Multithread illustration, where recalculations are done in a worker thread.

Mutexes Dialog-based application that creates two CWinThread objects and uses them
to do a task under the user's control.

Speakn Demonstrates multimedia sound using user-defined resources.

MFC samples - Controls

ノ Expand table

Sample Description
name

Button Demonstrates use of an in-place active menu, a stock property page, and the
About box control option.

Circ Demonstrates ActiveX control basics. These include control painting, stock and
custom properties, stock and custom events, use of colors and fonts, the stock Font
property page, the default property page, and versioning.

CmnCtrl Demonstrates some of the new controls available with MFC on wiprlhext: The
command link button ( CButton ), the pager control ( CPagerCtrl ), the split button
( CSplitButton ), and the network address control ( CNetAddressCtrl ).

Contain Demonstrates a Visual Editing Container Application.

Image Demonstrates how to use MFC to build an ActiveX control that downloads data
asynchronously.

Licensed A control that enforces use of a design-time and run-time license.

Localize A control with a localized user interface that demonstrates use of separate type
libraries and resource dynamic-link libraries (DLLs) for localization.

NetAddr Demonstrates use of the Windows Vista "Net Address Verifier" control.
Sample Description
name

Pal Control that displays the colors of a palette. It demonstrates read-only properties,
persistent Get/Set properties, persistent parameterized properties, and picture
properties.

Push Control subclassed from a Windows owner-drawn button control. It demonstrates


stock properties, custom events, and picture holders.

RegSvr Demonstrates the invocation of Self-Registration Code.

SpinDial A control with the visual appearance of a spin-dial that demonstrates property
page data validation.

TestHelp An ActiveX control that has its own help file and tooltips.

Time A control that is invisible at run time and fires a timer event at set intervals.
Demonstrates notification functions and ambient properties.

XList A control, subclassed from a Windows list box, that displays text or bitmap items.

MFC samples - General

ノ Expand table

Sample name Description

ClipArt The ClipArt directory contains sample resources that you can use to customize
the appearance of your application.

CmnCtrl1 Demonstrates how to create and change the styles of Windows Common
Controls using MFC classes (Part 1).

CmnCtrl2 Demonstrates how to create and change the styles of Windows Common
Controls using MFC classes (Part 2).

CTaskDialog Demonstrates various features of the CTaskDialog class.

CtrlBars Custom toolbar and status bar, dialog bar, and floating palette.

CtrlTest Owner-draw list box and menu, custom control, bitmap button, spin control.

DBVList Uses the CListView and CDaoRecordset classes to implement the virtual list
view functionality available for the list view common control.

DIBLook Demonstrates the Use of DIBs and Color Palettes.

DlgCbr32 Adding a toolbar and a status bar to a dialog-based application.


Sample name Description

DlgTempl Demonstrates the dynamic creation of dialog templates.

DockTool Dragging and floating toolbars that are dockable.

Dynamenu Dynamically modifying list of items in menus; handling commands not known
at compile time; and updating the status bar command prompt for such
commands.

FileDlgWatcher Creates a custom dialog box that illustrates what events are generated when
you create a CFileDialog .

Hello Illustrates a single application window with a menu and About box.

HelloApp Minimal MFC sample that illustrates that few lines of code are required to get
a window to appear on the screen.

ListHdr Demonstrates how to use the common control MFC classes CListCtrl and
CHeaderCtrl .

MDI MDI application that doesn't use documents and views.

MDIDocVw Updated version of the MDI sample that uses the document/view
architecture.

MMXSwarm Demonstrates how to use CImage , the __m64 data type, and device-
independent bitmaps (DIBs).

Modeless Demonstrates the use of an MFC CDialog object as a modeless dialog box.

Multipad Simple text editor that lets the user open and edit multiple text files at one
time.

Npp Demonstrates how to implement an interface (SDI) application similar to


Notepad. It allows you to edit text messages and send them to other users or
other systems through the Windows messaging API, or MAPI.

PropDlg Property sheets (dialogs).

RowList Illustrates full row selection in a list-view common control.

Scribble Provides simple illustrations of a wide breadth of MFC features.

SimpleImage Demonstrates loading, resizing, conversion, and saving images.

SnapVw Shows how to use property pages in an MDI child frame window.

Spiro A game that shows to use CImageList and how to use memory display
contexts in applications requiring animation effects.

Tracker Demonstrates various CRectTracker styles and options.


Sample name Description

VariantUse Demonstrates the use of the variant data type.

ViewEx Multiple views, scroll view, splitter windows.

MFC samples - Internet

ノ Expand table

Sample name Description

DHTMLExplore Demonstrates handling DHTML events and using DHTML DDX.

HTMLEdit Wraps the Internet Explorer MSHTML editing control.

MFCIE Demonstrates the MFC CHtmlView and CReBar Classes.

Scheduler Demonstrates how to create an HTML-based dialog box using the Visual C++
libraries classes.

MFC samples - OLE

ノ Expand table

Sample Description
name

ACDual Demonstrates how to add dual interface support to an MFC-based Automation


server.

AutoClik Illustrates Automation features. Includes AUTODRIV, a simple Automation client


application that drives the AUTOCLIK sample application.

CalcDriv Automation client.

DrawCli Full-featured object-oriented drawing application that is also an ActiveX Visual


Editing container.

HierSvr Demonstrates a Server Application with OLE Drag and Drop.

InProc An in-process Automation server that can be loaded as a DLL in the client's
address space.

IPDrive A simple Automation client application that drives the INPROC sample application.

MFCBind Shows how to create an Active document (formerly known as a DocObject)


container.
Sample Description
name

MFCCalc An Automation server that implements a simple calculator.

OClient ActiveX Visual Editing container application, with drag and drop.

OLEView Implementing an OLE object browser through custom OLE interfaces.

SuperPad Demonstrates a visual editing server that edits text using CEditView.

TstCon Implements an ActiveX control container using MFC's support for OLE embedding.
You can use TSTCON to test ActiveX controls, change their properties, and invoke
their methods.

WordPad Uses MFC's support for rich edit controls to create a basic word processor.

MFC samples - Utility

ノ Expand table

Sample Description
name

GUIDGen A simple dialog-based MFC application that generates globally unique identifiers.

Makehm A console application that produces a mapping between resource identifications


and Help contexts.

MFC samples - Visual C++ 2008 Feature Pack

ノ Expand table

Sample name Description

CustomPages Demonstrates how to add a custom page to the Toolbar


Customization dialog box.

DesktopAlertDemo Demonstrates how to implement a desktop alert dialog box (similar to


the dialog box of an instant messaging application).

DlgToolTips Demonstrates how to implement advanced tooltips for controls on a


dialog box.

DrawClient Demonstrates how to integrate support for a ribbon into a drawing


application with editing container support.
Sample name Description

DynamicMenu Demonstrates how to dynamically update a menu on the menu bar


and a popup menu at run-time.

Explorer Demonstrates how to implement a file system explorer that resembles


File Explorer. It has similar user interface elements and capabilities.

IEDemo Demonstrates how to implement an application similar to Internet


Explorer, with similar user interface elements and capabilities.

MDITabsDemo Demonstrates how to create an application that uses the new tabbed
MDI documents interface instead of the traditional MDI child
windows.

MenuSubSet Demonstrates how to dynamically remove specific menu items and


submenus at application startup.

MSMoneyDemo Demonstrates how to use MFC to create a user interface similar to


Microsoft Money.

MSOffice2007Demo Demonstrates how to implement an editor application similar to an


Office 2007 application, with similar user interface elements and
limited similar capabilities. The MSOffice2007Demo sample
implements a full ribbon user interface, much like an Office 2007
application. Some of the ribbon elements are connected to
capabilities in the application.

NewControls Demonstrates the capabilities of many of the controls implemented in


MFC. These controls include customizable buttons, color picker
controls and palettes, a font chooser, an image editor, a property grid,
a masked edit control, and shell list and tree controls.

OutlookDemo Demonstrates how to create an application similar to Outlook


2003/2007.

OutlookMultiViews Demonstrates how to switch between multiple views on a single


document in an SDI application. The sample uses the Outlook bar
control to list the available views and switch between them.

OwnerDrawMenu Illustrates how to draw popup menu items dynamically.

PaletteDemo Illustrates how to create a multi-column toolbar with an owner-draw


information area. Click 2, 3 or 4 buttons on the Standard toolbar to
change at runtime the number of columns of the custom toolbar.

PropSheetDemo Illustrates the following types of Property Sheet control: simple, with
tabs at the left side, with tree control at the left side, OneNote-style
tabs, list of items at the left side.

RebarTest Demonstrates a customizable Rebar control that hosts a toolbar.


Sample name Description

RibbonGadgets Illustrates various controls that can be hosted in the Ribbon Control.
At the bottom of the main frame, you can find the Source Code
window with source code text, which outlines how to create a
particular gadget.

RibbonMDI Demonstrates usage of Ribbon Control with Multi Document


Interface.

RollupPane Demonstrates a floating "information" pane, which automatically rolls


up. You can press the pin button on the caption of floating pane to
turn rolling on and off.

SetPaneSize Demonstrates how to set docking pane size programmatically.

Slider Demonstrates how to implement a toolbar button that hosts an


external control.

StateCollection Demonstrates how to implement an application that saves and loads


different states for the menu bar, toolbars, and docking windows.

StatusBarDemo Demonstrates how to add various advanced controls to a status bar.

TabbedView Demonstrates how to create a view that contains multiple tabbed


views, such as the tabs in an Excel workbook.

TabControl Demonstrates the MFC Tab Control and the different appearances it
has using different properties and visual managers.

TasksPane Demonstrates the MFC Task Pane classes and their different
appearances using various properties and visual managers.

ToolbarDateTimePicker Demonstrates how to integrate a date/time picker control with the


toolbar

ToolTipDemo Demonstrates how to use advanced MFC tooltip features.

TrayMenu Illustrates the ability to use MFC Control Bar menus with the system
tray icon. It's similar to the notification icons in the lower-right corner
of the display.

VisualStudioDemo Demonstrates how to implement an application with many of the


same user interface features and capabilities of Visual Studio. Many of
the Visual Studio user interface elements are demonstrated, including
a customizable docking menubar, toolbar, and windows.

WordPad Demonstrates how to implement an application that imitates the


functionality of WordPad, including the user interface elements and
some of the capabilities.
Sample name Description

WorkSpaceToolBar Demonstrates how to add a toolbar to a docking pane. It resembles


the toolbar in Solution Explorer in Visual Studio.

MFC samples - Windows Touch

ノ Expand table

Sample name Description

GestureDemo Demonstrates the Windows Touch support in MFC (requires touch hardware).

TouchDemo Demonstrates the Windows Touch support in MFC (requires touch hardware).

ODBC samples
ノ Expand table

Sample Description
name

odbcsql This sample demonstrates how to use ODBC APIs to Connect to and access
database.

OS samples
ノ Expand table

Sample Description
name

GetImage Demonstrates the Windows Image Acquisition (WIA) application programming


interfaces (APIs).

Unix samples
ノ Expand table
Sample name Description

Unix - Demonstrates a wrapper that maps flags from the Sun Forte and gcc
ccWrapper compilers to the Microsoft Visual C++ compiler (cl.exe).

Windows 8 samples
The Windows 8 Sample Pack includes all the app code examples developed and
updated for Windows 8. The sample pack provides a convenient way to download all
the samples at once. The samples in this sample pack are available in C#, C++, VB.NET,
and JavaScript. The Windows Samples Gallery contains code samples that exercise the
various new programming models, platforms, features, and components available in
Windows 8 and Windows Server 2012. These downloadable samples contain the Visual
Studio solution (sln) file, source files, assets, resources, and metadata necessary to
compile and run successfully.

More information is available about the programming models, platforms, languages,


and APIs demonstrated in each sample. See the guidance, tutorials, and reference
articles provided in the Windows 8 documentation, available in the Windows Developer
Center. These samples are provided as-is, to demonstrate the functionality of the
programming models and feature APIs for Windows 8 and Windows Server 2012.

ノ Expand table

Sample name Description

Background Transfer This sample demonstrates the power-friendly, cost-aware, and


sample (Windows 8) flexible behavior of the Background Transfer API for Windows
Runtime applications. Provided sample scenarios cover file
downloads and uploads.

CryptoWinRT sample This sample shows how to use the new Cryptography APIs.
(Windows 8)

Print sample (Windows 8) This sample demonstrates how apps can integrate the Windows
print experience. The scenarios demonstrated in this sample
include: Printing from the app by using the charms bar and the print
contract, Printing from within the app experience, and more.

HttpClient sample This sample demonstrates the use of the HttpClient class and the
(Windows 8) IXMLHTTPRequest2 interface to upload and download various types
of content from an HTTP server using the networking features
provided by the Windows Runtime.

Accelerometer sensor This sample shows how to use the


sample (Windows 8) Windows.Devices.Sensors.Accelerometer API. This sample allows the
Sample name user to view the acceleration forces along the X-, Y-, and Z-axes for
Description
a 3-axis accelerometer. You can choose one of three scenarios.

Account picture name This sample demonstrates different ways of getting the name of the
sample (Windows 8) user that is currently logged in. It also demonstrates how to get and
set the image used for the user's tile.

App settings sample This sample demonstrates how to use the ApplicationSettings API
(Windows 8) and settings flyouts to integrate an app's settings UI with the
Settings charm. The sample uses the
Windows.UI.ApplicationSettings namespace and
WinJS.UI.SettingsFlyout .

Windows Store device app This sample demonstrates how to create a Windows Store device
for camera sample app for a camera. A Windows Store device app is provided by an
(Windows 8) IHV or OEM to differentiate the capture experience for a particular
camera.

Getting started with C++ The sample demonstrates some basic principles of Windows Store
simple blog reader sample app development in native C++ using XAML to define the user
(Windows 8) interface. It's a complete working version of the application
discussed on the Windows Developer Center.

Reading and writing data This sample shows how to use the DataReader and DataWriter
sample (Windows 8) classes to store and retrieve data.

Application data sample This sample shows you how to store and retrieve data that is
(Windows 8) specific to each user and Windows Store app using the Windows
Runtime application data APIs. Application data includes session
state, user preferences, and other settings.

Custom driver access This sample shows how to use CreateDeviceAccessInstance and
sample (Windows 8) IDeviceIoControl to access a specialized device.

XAML ListView and This sample demonstrates how to use the GridView and ListView
GridView essentials sample controls.
(Windows 8)

Animation metrics sample This sample shows how to use the Animation Metrics APIs in
(Windows 8) Windows.UI.Core.AnimationMetrics to access the raw parameters
that define the animations in the Windows Animation Library.

Playback Manager This sample demonstrates how to select the correct


msAudioCategory sample msAudioCategory category for an audio-video (AV) stream to
(Windows 8) configure it as an audio playback stream.

XAML DirectX 3D shooting This sample demonstrates the implementation of a simple first
game sample (Windows 8) person 3-D game using DirectX (Direct3D 11.1, Direct2D, XInput,
and XAudio2) and XAML in a C++ app. XAML is used for the heads-
up display and game state messages.
Sample name Description

XAML scrolling, panning, This sample demonstrates how to use the ScrollViewer control to
and zooming sample pan and zoom.
(Windows 8)

XAML FlipView control This sample demonstrates how to use the FlipView control to
sample (Windows 8) enable users to flip through a collection.

Gyrometer sensor sample This sample shows how to use the


(Windows 8) Windows.Devices.Sensors.Gyrometer API. This sample allows the user
to view the angular velocity along the X-, Y-, and Z-axis for a 3-axis
gyrometer.

Device app for printers This sample shows how to create a device app for printers that can
SDK sample (Windows 8) be activated from the tile contract, the printTaskSettings contract,
and from toast displayed by backgroundTask in response to print
driver event.

Background task sample This sample shows you how to create and register background tasks
(Windows 8) using the Windows Runtime background task API. A background
task is triggered by a system or time event, and can be constrained
by one or more conditions.

StreamSocket sample This sample demonstrates the basics of the StreamSocket class
(Windows 8) using the networking features provided by the Windows Runtime.
The client component of the sample creates a TCP socket to make a
network connection, uses the socket to send data, and more.

Scheduled notifications This sample shows how to use scheduled and recurring tile updates
sample (Windows 8) and toast notifications for an app. This ability enables you to specify
a precise time to deliver the notification, even if the app isn't
running.

Playback Manager This sample demonstrates how to select the correct


Companion Sample msAudioCategory category for an audio-video stream to configure
(Windows 8) it as an audio playback stream.

OrientationSensor sample This sample shows how to use the


(Windows 8) Windows.Devices.Sensors.OrientationSensor API. It allows the user
to view the rotation matrix and Quaternion values that reflect the
current device orientation.

File access sample This sample shows how to create, read, write, copy and delete a file,
(Windows 8) how to retrieve file properties, and how to track a file or folder so
that your app can access it again. This sample uses Windows.Storage
and Windows.Storage.AccessCache API.

Removable storage sample The removable storage sample demonstrates how to transfer files
(Windows 8) to and from removable storage devices. This sample requires a
Sample name Description

removable storage device connected to the system, such as a


camera, media player, cellular phone, or a USB thumb drive.

XAML SurfaceImageSource This sample demonstrates how to use a SurfaceImageSource to


DirectX interop sample include DirectX content in your XAML app. This sample uses both
(Windows 8) C++ and C#.

Connecting with This sample demonstrates how to use WebSockets in a connected


WebSockets sample Windows Store app. The sample covers basic functionality, such as
(Windows 8) how to make a connection, send and receive data, and close the
connection.

Configure keys for media This sample demonstrates how to configure the hardware media
sample (Windows 8) keys on a keyboard. Then, how to use the configured keys to
control an audio-video stream by pressing or clicking play, pause,
stop, and so on.

XAML personality This sample demonstrates how to use the built-in personality
animations sample animations in your app.
(Windows 8)

Toast notifications sample This sample shows how to use toast notifications: Ones that appear
(Windows 8) as pop-up notifications in the upper right corner of the screen. A
user can select the toast (touch or click) to launch the associated
app.

Contact Picker app sample This sample demonstrates how to use the Contact Picker to select
(Windows 8) one or more contacts. It also includes a basic implementation of the
Contact Picker APIs to demonstrate how to display a list of contacts
to the user.

DirectX marble maze game This sample demonstrates how to build a basic 3D game using
sample (Windows 8) DirectX. This game is a simple labyrinth game where the player is
challenged to roll a marble through a maze of pitfalls using tilt
controls.

DirectX postcard app This sample demonstrates the implementation of a simple Windows
sample (Windows 8) Store app using DirectX with C++ for postcard creation using
DirectX and XAML interop.

DirectX 3D shooting game This sample demonstrates the implementation of a simple first
sample (Windows 8) person 3-D game using DirectX (Direct3D 11.1, Direct2D, XInput,
and XAudio2) in a C++ app.

XAML AppBar control This sample demonstrates how to use the AppBar control to present
sample (Windows 8) navigation, commands, and tools to users. The app bar is hidden by
default and appears when users swipe a finger from the top or
bottom edge of the screen.
Sample name Description

Date and time formatting This sample demonstrates how to use the DateTimeFormatter class
sample (Windows 8) in the Windows.Globalization.DateTimeFormatting namespace to
display dates and times according to the user's preferences.

Secondary tiles sample This sample shows how to pin and use a secondary tile. That's a tile
(Windows 8) that directly accesses a specific, non-default section or experience
within an app, such as a saved game, or a specific friend in a social
networking app.

Input Touch hit testing This sample uses a polygon shapes puzzle to demonstrate how to
sample (Windows 8) handle pointer input, implement custom hit testing for touch input,
and process manipulations in a Windows Store app using C++ and
DirectX.

Network information This sample demonstrates how to use the Windows Runtime
sample (Windows 8) Network Information APIs.

Input Simplified ink sample This sample demonstrates how to use ink functionality in Windows
(Windows 8) Store apps.

StorageDataSource and This sample shows how to retrieve and display images in the user's
GetVirtualizedFilesVector Pictures Library.
sample (Windows 8)

Edge-based gesture This sample shows how to listen for events that occur in edge-
invocation sample based UI, using the EdgeGesture class.
(Windows 8)

Check if current session is This sample demonstrates the use of Windows.System.RemoteDesktop


remote sample (Windows API.
8)

Application resources and This sample shows how to use application resources to separate
localization sample localizable content from application code. The sample uses the
(Windows 8) Windows.ApplicationModel.Resources.Core and
Windows.Globalization namespaces, and WinJS.Resources .

Context menu sample This sample shows how to create a context menu and how to
(Windows 8) replace the default context menu for text. This sample uses
Windows.UI.Popups API, including the PopupMenu and the
oncontextmenu event.

Geolocation sample The Geolocation sample demonstrates how to use the Geolocation
(Windows 8) API to get the geographic location of the user's PC. An app can use
the Geolocation API to get location one time, or it can continuously
track the location.

Message dialog sample This sample demonstrates how to use a MessageDialog for
(Windows 8) displaying dialogs, setting commands and their actions, and
Sample name Description

changing the default button. The Windows.UI.Popups namespace


contains the MessageDialog class.

MediaStreamSource media This sample shows how to support the Microsoft Silverlight
extension sample MediaStreamSource concept in a Windows Store app.
(Windows 8)

DirectWrite vertical text This sample uses DirectWrite and Direct2D to properly display
sample (Windows 8) vertical text in a custom layout shape.

DXGI swap chain rotation This sample demonstrates the IDXGISwapChain1::SetRotation


sample (Windows 8) method and how you can use the method in conjunction with
prerotated content to improve presentation performance.

Direct2D custom image This sample demonstrates how to implement custom Direct2D
effects sample (Windows 8) Effects using standard pixel, vertex, and compute shaders.

DirectX touch input sample This sample demonstrates touch and mouse navigation of a 3-D
(Windows 8) environment in a C++ app with Direct3D.

XInput game controller This sample demonstrates the use of the XInput APIs in a C++ app.
sample (Windows 8) It reads input from an Xbox game controller and displays data
about the analog stick movements and button presses.

Direct3D-Direct2D interop This sample shows how to interoperate with Direct2D and
sample (Windows 8) DirectWrite to write text to a Direct3D render target. It's an effective
way to create heads-up displays and text-based readouts such as
scoring panels in games and 3-D apps.

Syndication sample This sample demonstrates a basic Windows Store app for Windows
(Windows 8) 8 that can retrieve feeds from a web service. This sample is currently
provided in the JavaScript, C#, C++, and VB programming
languages.

App tiles and badges This sample shows how to use an app tile, which is the
sample (Windows 8) representation and launch point for your app in the Start screen. It
also shows how to use a badge on that tile. It's a method for the
app to relay status information to the user when the app isn't
running.

XAML user and custom This sample demonstrates how to create and use XAML
controls sample (Windows UserControl elements and create custom controls for your projects.
8)

Direct3D resource loading This sample demonstrates Direct3D resource loading for C++ apps
sample (Windows 8) with DirectX.

XAML ListView and This sample demonstrates the interaction model of the ListView
GridView customizing control.
Sample name Description

interactivity sample
(Windows 8)

XAML WebView control This sample demonstrates how to use the WebView control to
sample (Windows 8) display a URL, load HTML, interact with script within a WebView , and
use WebViewBrush .

Compass sensor sample This sample demonstrates how to use the


(Windows 8) Windows.Devices.Sensors.Compass API. This sample allows the user
to view the compass reading as a magnetic-north and, depending
on the installed sensor, a true-north value.

Display orientation sample This sample demonstrates how to use the DisplayProperties class
(Windows 8) to set the display orientation in an app.

Direct2D interpolation This sample shows the various interpolation modes used by
modes sample (Windows Direct2D.
8)

Globalization preferences This sample demonstrates how to use the


sample (Windows 8) Windows.System.UserProfile.GlobalizationPreferences class to
obtain the user's globalization preferences. It also shows how to use
the GeographicRegion and Language classes.

Direct2D geometry This sample shows how multi-core geometry tessellation can help
realization sample reduce geometry rendering time. Using opacity masks and meshes
(Windows 8) is an alternative to traditional geometry rendering that may be
better in some situations.

Language font mapping This sample demonstrates how to obtain language-specific font
sample (Windows 8) recommendations using the LanguageFontGroup class in the
Windows.Globalization.Fonts namespace.

Inclinometer sensor sample This sample shows how to use the


(Windows 8) Windows.Devices.Sensors.Inclinometer API. This sample allows the
user to view the angles of incline about the X-, Y-, and Z-axis for a
3-axis inclinometer.

XAML high contrast style This sample demonstrates various techniques for implementing
sample (Windows 8) support for high contrast mode in your app. Support for high
contrast mode is important to make your app accessible to people
with eyesight problems.

Input Device capabilities This sample demonstrates how to query the input devices that are
sample (Windows 8) connected to the user's device. And, how to support the pointer,
touch, pen/stylus, mouse, and keyboard input modes of Windows
Store apps.
Sample name Description

EAS policies for mail clients This sample shows how mail clients can retrieved device information
sample (Windows 8) and work with supplied Exchange Active Sync (EAS) policies.
Windows Store apps can configure their mail clients to stay
compliant with the given EAS policies.

DatagramSocket sample This sample demonstrates the basics of the DatagramSocket class
(Windows 8) using the networking features provided by the Windows Runtime.
The client component of the sample creates a UDP socket, uses the
socket to send and receive data, and closes the socket.

DirectWrite hello world This sample shows how to use DirectWrite and Direct2D to render
sample (Windows 8) the text "Hello World" to a CoreWindow .

Compression sample This sample demonstrates how to read structured data from a file
(Windows 8) and write compressed data to a new file and how to read
compressed data and write decompressed data to a new file. Many
applications need to compress and decompress data.

Network status This sample demonstrates how to determine a change in Internet


background sample connection profile by registering a background task handler for
(Windows 8) Network Status Change event using an Internet Present condition.

App package information This sample shows you how to get package information using the
sample (Windows 8) Windows Runtime packaging API. Users acquire your Windows
Store app as an app package. Windows uses the information in an
app package to install the app on a per-user basis.

LightSensor sample This sample shows how to use the


(Windows 8) Windows.Devices.Sensors.LightSensor API. This sample allows the
user to view the ambient light reading as a LUX value. You can
choose one of two scenarios: LightSensor data events, Current light
sensor readings, and more.

Mobile broadband account This sample demonstrates how to use the Windows 8 Mobile
provisioning sample Broadband provisioning agent API
(Windows 8) ( Windows.Networking.NetworkOperators.ProvisioningAgent ) to
configure Windows 8 with required connectivity information and
access provisioning.

Media Play To sample This sample demonstrates the Play To API. It shows how you can
(Windows 8) expand your media application to stream video, audio, and images
to other devices on your local network.

Input Touch keyboard This sample demonstrates how to launch the touch keyboard
sample (Windows 8) automatically in custom controls that aren't derived from platform
controls. The sample implements custom controls that require
keyboard input and aren't derived from standard XAML controls.
Sample name Description

XAML animation library This sample demonstrates how to animate elements and apply
sample (Windows 8) easing functions to the animations to achieve various effects.

Snap sample (Windows 8) The snapped state is one of the four possible application view
states. Snapping an app resizes the app to 320 pixels wide, which
allows it to share the screen with another app. Snapping enables
two apps to be visible at the same time.

Transcoding media sample This sample demonstrates how to use the


(Windows 8) Windows.Media.Transcoding API to transcode a video file in a
Windows Store app. Transcoding is the conversion of a digital
media file, such as a video or audio file, from one format to another.

XAML two-dimensional This sample demonstrates how to use two-dimensional transforms


transforms sample to modify how elements are displayed in your app. A transform
(Windows 8) defines how to map, or transform, points from one coordinate
space to another coordinate space.

IXmlReader and IXmlWriter This sample demonstrates how to use IXmlReader and IXmlWriter
XML data read write in your Windows Store app with C++. They're used to read and
sample (Windows 8) write XML data from a flat XML-formatted text file. These interfaces
are part of the Windows Win32 and COM APIs, but are supported
by the Windows Runtime.

Media capture using This sample demonstrates how to use the MediaCapture API to
capture device sample capture video, audio, and pictures from a capture device, such as a
(Windows 8) webcam.

XAML Popup sample This sample demonstrates how to create and use the XAML Popup
(Windows 8) element in your projects.

CameraCaptureUI Sample This sample demonstrates how to use the


(Windows 8) Windows.Media.Capture.CameraCaptureUI API, which displays a full-
screen UI for capturing photos or videos. The Camera Capture UI
provides controls for switching from photo to video, a timer for
taking time-delayed photos, and more.

XAudio2 audio file This sample demonstrates the use of XAudio2 in an app.
playback sample (Windows
8)

Hilo C++ sample This sample demonstrates how to build a complete Windows Store
(Windows 8) app using C++ and XAML. The Hilo photo sample provides
guidance to C++ developers that want to create a Windows 8 app
using modern C++, XAML, and the Windows Runtime.

DirectWrite custom text This sample shows how to implement a custom text renderer for
renderer sample (Windows DirectWrite.
8)
Sample name Description

DirectWrite font This sample shows how to use DirectWrite to list the fonts in the
enumeration sample system font collection on a user's device.
(Windows 8)

Direct2D perspective This sample shows how to use the DrawBitmap API to display an
transform sample image with a perspective transform applied to it.
(Windows 8)

CameraOptionsUI Sample This sample demonstrates how to use camera options in a device
(Windows 8) app. The CameraOptionsUI API displays a UI for adjusting camera
settings. This sample requires a webcam.

XInput audio controller This sample demonstrates XAudio2 playback to an XInput device,
playback sample (Windows such as a headset, in an app.
8)

Direct2D 3D transform This sample demonstrates the different methods to transform an


effect sample (Windows 8) image in 3-D space.

Windows account This sample demonstrates how to use the members of the
authorization sample Windows.Security.Authentication.OnlineId namespace to
(Windows 8) authenticate a user with their Microsoft Account in delegation
mode. And, how to send acquired tokens to Live Connect APIs
using REST protocol.

Number formatting and This sample demonstrates how to use the DecimalFormatter ,
parsing sample (Windows CurrencyFormatter , PercentFormatter , and PermilleFormatter
8) classes in the Windows.Globalization.NumberFormatting namespace.
They're used to display and parse numbers, currencies, and percent
values.

DXGI offer and reclaim This sample demonstrates the use of the DXGI
resources sample IDXGIDevice2::OfferResources and IDXGIDevice2::ReclaimResources
(Windows 8) APIs in a C++ app with DirectX.

Web authentication broker This sample demonstrates the web authentication broker WinRT
sample (Windows 8) API. It lets you enable single sign-on (SSO) connections to OAuth
providers such as Facebook, Google, Microsoft, and Twitter.

XAudio2 audio stream This sample demonstrates audio streaming in a C++ app using the
effect sample (Windows 8) XAudio2 and Media Foundation APIs.

Splash screen sample This sample shows how to imitate the splash screen that Windows
(Windows 8) displays for your app, by positioning a similar image correctly when
Windows dismisses the splash screen that it displays.

SMS background task This sample shows how to use the Windows 8 Mobile Broadband
sample (Windows 8) SMS API ( Windows.Devices.Sms ) with the Background Task API
Sample name Description

( Windows.ApplicationModel.Background ) to send and receive SMS


text messages.

SMS message send, This sample shows how to use the Windows 8 Mobile Broadband
receive, and SIM SMS API ( Windows.Devices.Sms ).
management sample
(Windows 8)

Trial app and in-app This sample demonstrates how to use the licensing API provided by
purchase sample (Windows the Windows Store to determine the license status of an app, or of a
8) feature enabled by an in-app purchase.

Input Touch keyboard text This sample shows how to enable optimized views on the touch
input sample (Windows 8) keyboard. It works by using input scopes and input types with
controls in the WinJS.UI namespace, and with the TextBox and
RichEdit XAML controls.

XAML text editing sample This sample demonstrates how to use text input controls in your
(Windows 8) app.

Thread pool sample This sample shows you how to run work items asynchronously using
(Windows 8) the Windows Runtime thread pool API.

UI Automation core This sample demonstrates how to create a Microsoft UI Automation


window provider sample provider. It makes programmatic information about a Windows
(Windows 8) Store app available to accessible technologies such as screen
readers. The sample is a Direct2D application.

XAML accessibility sample This sample shows you how to add basic accessibility support to
(Windows 8) your app.

Playlist sample (Windows This sample demonstrates how to create, save, display, and edit a
8) playlist of audio files. This sample uses classes that are in the
Windows.Media.Playlists namespace.

Media Server client sample This sample demonstrates how to create a Media Server client using
(Windows 8) the Media Server API. The Media Server sample demonstrates how
to browse a Digital Media Server programmatically on your local
network, and display all of its video files.

Direct2D magazine app This sample shows how to use Direct2D, DirectWrite, Windows
sample (Windows 8) Imaging Component (WIC), and XAML to build an app with a
magazine-type presentation.

Mobile broadband account This sample shows how to use the Windows 8 Mobile Broadband
and device management API ( Windows.Networking.NetworkOperators ) employed by Mobile
sample (Windows 8) Network Operators (MNO). It demonstrates how to use the
MobileBroadbandAccount APIs to retrieve and display available
Mobile Broadband accounts.
Sample name Description

Proximity sample This sample demonstrates how to use the PeerFinder and
(Windows 8) ProximityDevice classes to communicate with nearby computers.
You can use the Proximity API to exchange small messages during
a tap gesture or set up a socket connection between peer apps.

Creating a Windows This sample shows how to create a component in C++/CX that's
Runtime in-process used in C++/CX, JavaScript, and C# client code. The OvenServer
component sample project contains a runtime class named Oven , which implements an
(C++CX) (Windows 8) IOven interface and an IAppliance interface.

Device auto rotation This sample shows how to use the DisplayProperties class to
preferences sample handle and verify device rotation events.
(Windows 8)

Real-time communication This sample demonstrates how to use the low latency feature to
sample (Windows 8) enable real-time communication applications.

Sharing content source This sample demonstrates how an app can share content with
app sample (Windows 8) another app. This sample uses classes from the
Windows.ApplicationModel.DataTransfer namespace.

Search contract sample This sample shows how to let users search your app when they
(Windows 8) select the Search charm and open the search pane. And, how to use
the search pane to display suggestions for users' queries.

Raw notifications sample This sample shows how to use raw notifications, which are push
(Windows 8) notifications with no associated UI that perform a background task
for the app.

Direct2D basic image This sample shows how to load an image, apply the Gaussian blur
effects sample (Windows 8) effect to it, and then display it in a Windows::UI::Core::CoreWindow .

Direct2D effects on This sample shows how to apply image effects to Direct2D
primitives sample primitives. This sample draws rounded rectangles using Direct2D
(Windows 8) and then draws DirectWrite text in the middle of the rectangles.
Then it applies an effect graph to it.

ControlChannelTrigger The sample shows how to use the ControlChannelTrigger class in a


StreamSocket sample Windows Store app. It uses a TCP StreamSocket , so the app is
(Windows 8) always connected and always reachable. This sample demonstrates
the use of background network notifications.

ControlChannelTrigger The sample shows how to use the ControlChannelTrigger class to


StreamWebSocket sample enable a Windows Store app using a StreamWebSocket to be
(Windows 8) always connected and always reachable. This sample demonstrates
the use of background network notifications.

Association launching This sample shows you how to launch the user's default app for file
sample (Windows 8) type or a protocol. You can also learn how to enable your app to be
the default app for a file type or a protocol.
Sample name Description

AtomPub sample This sample demonstrates how to access, create, update, and
(Windows 8) remove syndicated content feeds from the web. It uses the
Windows Runtime implementation of the Atom Publication
standard.

Certificate enrollment This sample demonstrates how to create and enroll a certificate in a
sample (Windows 8) certification hierarchy. To obtain an evaluation copy of Windows 8,
go to Windows 8. To obtain an evaluation copy of Microsoft Visual
Studio 2012, go to Visual Studio 2012.

Clipboard app sample This sample demonstrates how an app can use clipboard
(Windows 8) commands, including copy, paste, cut, and move. This sample uses
classes from the Windows.ApplicationModel.DataTransfer
namespace.

Direct2D composite effect This sample shows the wide range of composite and blend modes
modes sample (Windows available from Direct2D.
8)

Direct3D bump mapping This sample demonstrates bump mapping using a normal map and
sample (Windows 8) per-pixel lighting.

Calendar details and math This sample demonstrates how to use the Calendar class in the
sample (Windows 8) Windows.Globalization namespace to manipulate and process dates
based on a calendar system and the user's globalization
preferences.

Device enumeration This sample shows how to use the Device Enumeration API to find
sample (Windows 8) available devices and look for device information. The sample
presents two scenarios: In the first scenario, the Device Enumeration
API is used to look for specific device interfaces.

DirectWrite paragraph text This sample shows how to use DirectWrite and Direct2D to render
sample (Windows 8) paragraph text to a CoreWindow . And, apply justification and
character spacing to the layout.

Responding to the [This documentation is preliminary and is subject to change.] This


appearance of the on- sample shows how to listen for and respond to the appearance of
screen keyboard sample the onscreen soft keyboard. When focus is given to an element that
(Windows 8) requires text input on a device that doesn't have a keyboard.

XAML data binding sample This sample demonstrates basic data binding techniques using the
(Windows 8) Binding class and Binding markup extension.

Direct3D tutorial sample This sample is a five-lesson tutorial. It provides an introduction to


(Windows 8) the Direct3D API, and introduces the concepts and code used in
many of the other DirectX samples.

Direct2D effects photo This sample shows various common photo manipulation techniques
adjustment app sample using Direct2D Effects. This sample is divided into several parts.
Sample name Description

(Windows 8) Lesson 1: Shows the basics of loading and drawing an image using
Direct2D Effects.

Windows Audio Session Demonstrates how to do various audio related tasks using the
(WASAPI) sample Windows Audio Session API (WASAPI).
(Windows 8)

User domain name sample This sample demonstrates the domain-related functionality
(Windows 8) provided by the UserInformation class of the
Windows.System.UserProfile namespace. The UserInformation class
enables an app to get and set information about the user.

USSD message This sample demonstrates network account management using the
management sample USSD protocol with GSM-capable mobile broadband devices. USSD
(Windows 8) is typically used for account management of a mobile broadband
profile by the Mobile Network Operator (MNO).

Bing Maps Trip Optimizer The sample demonstrates how to use JavaScript and Visual C++
sample (Windows 8) and to create app for Windows 8 named Bing Maps Trip Optimizer.
Bing Maps Trip Optimizer uses JavaScript to define the UI, and C++
for a computationally expensive algorithm in parallel.

Direct2D and DirectWrite This sample shows how to use Direct2D and DirectWrite to render a
animated text on a path string of text along an animated, non-linear geometric path. The
sample (Windows 8) app renders "Hello, World!" repeated several times in different
languages along a Bezier curve.

Wi-Fi hotspot This sample demonstrates how to use the Windows 8 Mobile
authentication sample Broadband API ( Windows.Networking.NetworkOperators ) for Wi-Fi
(Windows 8) hotspot authentication. Use this mechanism as an alternative to
configuring static credentials for a Wi-Fi hotspot.

XAML images sample This sample demonstrates various techniques for displaying and
(Windows 8) manipulating images in your app using the Image control and the
BitmapImage class.

HomeGroup app sample This sample demonstrates how to use a HomeGroup to open, search,
(Windows 8) and share files. This sample uses some of the HomeGroup options
found in the Windows.Storage.Pickers and
Windows.Storage.KnownFolders .

UI contrast and settings This sample shows how to use the UI settings APIs in a basic C# or
sample (Windows 8) JavaScript app.

Folder enumeration This sample shows how to list the top-level files and folders inside a
sample (Windows 8) location. (For example, a folder, device, or network location.) And,
how to use queries to list all files inside a location by sorting them
into file groups.
Sample name Description

File picker sample This sample shows how to access files and folders by letting the
(Windows 8) user choose them through the file pickers. And, how to save a file
so that the user can specify the name, file type, and location of a file
to save.

File picker contracts This sample shows how an app can provide files, a save location,
sample (Windows 8) and real-time file updates to other apps through the file picker. It's
done by participating in the File Open Picker contract, File Save
Picker contract, and Cached File Updater contract.

Programmatic file search This sample shows how to query files in locations such as a folder,
sample (Windows 8) library, device, or network location. It uses Windows.Storage.Search
API. Important APIs in this sample include: QueryOptions class,
StorageFileQueryResult class, and others.

File and folder thumbnail This sample shows how to retrieve thumbnails for files and folders.
sample (Windows 8) It uses Windows.Storage.FileProperties API.

Input Manipulations and This sample demonstrates how to handle pointer input and process
gestures (C++) sample manipulations and gestures with the GestureRecognizer APIs in a
(Windows 8) Windows Store app using C++ and DirectX.

Direct3D HLSL fractal This sample demonstrates the use of Direct3D HLSL and
generator sample DirectCompute compute shaders to create fractal images.
(Windows 8)

XAML Direct2D lighting This sample demonstrates the lighting effects available in Direct2D
effects sample (Windows 8) Effects. The lighting effect properties are controlled by XAML
interface controls and then displayed using Direct2D via a XAML
SwapChainBackgroundPanel.

Direct2Dapp printing This sample demonstrates how to add Direct2D printing support to
sample (Windows 8) a Windows Store app. This sample shows how to use Direct2D
features to render the content of a Windows Store app for printing.
And, how to send the rendered content to the printer.

Direct2D printing images This sample demonstrates how to print Direct2D images and
and effects sample Direct2D effects in a Windows Store app.
(Windows 8)

Direct2D animated text This sample shows how to render text quickly by using the Direct2D
sample (Windows 8) FillOpacityMask method. The sample also responds to touch. A two
finger pinch can be used to zoom the text in and out.

Direct3D post-processing This sample demonstrates Direct3D 11.1 post-processing on a


effects sample (Windows 8) simple rotating cube scene, using down-scaled intermediate
buffers.
Sample name Description

Extended Linguistic This sample demonstrates the use of Extended Linguistic Services
Services (ELS) sample (ELS) in a Windows Store app. The sample implements scenarios
(Windows 8) that demonstrate the use of the three available ELS services. The
scenarios demonstrate how to request a specific service.

DirectWrite hit testing This sample shows how to use the hit-testing features of
sample (Windows 8) DirectWrite. They're used to determine which part of the displayed
text is being clicked or touched.

DirectWrite inline object This sample shows how to insert an inline object into a text layout,
sample (Windows 8) such as an image.

XAML vector-based This sample demonstrates how to draw vector-based graphics in


drawing sample (Windows your app.
8)

Bluetooth call control The Bluetooth CallControl sample demonstrates how to configure
sample (Windows 8) the default Bluetooth communications device for handling calls.
There are JavaScript, C#, C++, and VB.Net versions of this sample.
This sample requires knowledge of Windows events and event
handling.

Direct2D command list This sample demonstrates the use of a command list. It's used for
sample (Windows 8) recording a set of vector commands, creating an image brush from
the command list, and then filling a rectangle geometry with it. The
command list preserves resolution independence of the vector.

ControlChannelTrigger The sample shows how to use the ControlChannelTrigger class to


XMLHTTPRequest sample enable a Windows Store app using IXMLHTTPRequest2 to be always
(Windows 8) connected and always reachable. This sample demonstrates the use
of background network notifications in a Windows Store app.

XInput and JavaScript This sample demonstrates how to wrap the XInput C++ API in a
controller sketch sample Windows Runtime component. Then, it calls it from a Windows
(Windows 8) Store app using JavaScript. This sample implements a sketch app
that lets you use the Xbox game controller to select line thickness
and more.

Direct2D convolve matrix This sample demonstrates the Direct2D Effects convolve matrix
effect sample (Windows 8) effect. This sample has some example convolution kernel matrices:
Passthrough (no-op), Box blur (width 5), Simple edge detect, Simple
sharpen, Emboss, Vertical smear (height 10) theses and more.

DirectX swap chain This sample shows how to receive CoreWindow events in a native
implementation sample application, and how to connect a DirectX swap chain to the
(Windows 8) application view.

Credential picker sample This sample shows how to use the


(Windows 8) Windows.Security.Credentials.UI.CredentialPicker class to retrieve
Sample name Description

credentials. These credentials may be passed to APIs that require


them, for example, HttpClient .

Direct2D animation sample This sample shows how to use Direct2D to render and animate a
(Windows 8) Direct2D primitive along a spiral path.

Sharing content target app This sample demonstrates how an app can receive content shared
sample (Windows 8) from another app. This sample uses classes from the
Windows.ApplicationModel.DataTransfer and
Windows.ApplicationModel.DataTransfer.Share namespaces.

Direct2D save to image file This sample shows how to render to the screen using Direct2D and
sample (Windows 8) DirectWrite. And, how to save the rendered image to disk using the
WIC API.

Scaling according to DPI This sample describes how to build an app that scales according to
sample (Windows 8) the pixel density of the screen. It loads images of the right scale or
overrides default scaling. This sample uses the
Windows.Graphics.Display API.

Creating a Windows This sample shows how to create a component in C# that's used in
Runtime in-process C++/CX, JavaScript, and C# client code. The OvenServer project
component sample (C#) contains a runtime class named Oven , which implements an IOven
(Windows 8) interface and an IAppliance interface.

Push and periodic This sample shows how a client app can register and listen for push
notifications client-side notifications sent from a web server. Push notifications can be used
sample (Windows 8) to update a badge or a tile, raise a toast notification, or launch a
background task.

Portable device API sample This sample shows how to access the IPortableDevice COM API
(Windows 8) from a C++ app. To learn how to access the IPortableDevice COM
API from a Desktop C++ app, refer to the Portable Devices COM
API Sample.

PlayToReceiver sample This sample demonstrates how to create a software Play To receiver.
(Windows 8) To advertise the software Play To Receiver, click the Start Receiver
button. To stop the receiver, click the Stop Receiver button.

Lock screen This sample demonstrates how to use the LockScreen API to set the
personalization sample current user's lock screen image. This sample uses classes from the
(Windows 8) Windows.System.UserProfile namespace.

Credential locker sample This sample demonstrates how to use the WinRT PasswordVault
(Windows 8) APIs, and how to use the credential locker to store web credentials.
Specific scenarios include a single user with a single resource, and
multiple users with a single resource.
Sample name Description

Media engine native C++ This sample demonstrates video playback using the MediaEngine
video playback sample API in a native C++ app.
(Windows 8)

Media extensions sample This sample demonstrates how to use media extensions. You can
(Windows 8) apply effects to video, decode video, and create media streams
using scheme handlers.

Lock screen apps sample This sample shows how an app can have a presence on the lock
(Windows 8) screen—the screen that is shown when the computer is locked—
with a badge to provide basic status information or a tile to provide
more detailed status.

XAML text display sample This sample demonstrates how control the appearance of text in
(Windows 8) your app.

SimpleOrientationSensor This sample shows how to use the


sample (Windows 8) Windows.Devices.Sensors.SimpleOrientationSensor API.

Direct3D sprite sample This sample provides a Direct3D implementation of sprite batch
(Windows 8) behaviors, similar to the XNA SpriteBatch API. Sprites are 2-D
bitmaps that can be transformed and managed independently in a
3-D scene, typically used in 2-D games.

Direct3D stereoscopic 3D This sample demonstrates how to add a stereoscopic 3-D effect to
sample (Windows 8) C++ apps by using Direct3D. It also demonstrates how to respond
to system stereo changes in Direct3D. The stereoscopic 3-D effect
requires a display that supports stereo 3-D.

Creating a Windows This sample shows how to create an in-process DLL component in
Runtime DLL component Microsoft Visual C++. It's used in C++/CX, JavaScript, and C# client
with C++ sample code. The OvenServer project contains a runtime class named Oven ,
(Windows 8) which implements an IOven interface.

Creating a Windows This sample shows how to create an out-of-process EXE component
Runtime EXE component in Microsoft Visual C++. It's used in C++/CX, JavaScript, and C#
with C++ sample client code. The OvenServer project contains a runtime class named
(Windows 8) Oven , which implements an IOven interface.
Microsoft C/C++ help and community
Article • 09/27/2022

Here's where to get help and information about how to write C++ code and use the
Visual Studio development tools.

Samples
Developer Code Samples: Contains downloadable sample code from Microsoft and
community contributors.

Product documentation
C++ in Visual Studio: Contains reference and conceptual documentation about
Visual C++.

Windows Developer Center: Contains information about how to use C++ and
other languages to develop apps for Windows.

Online and offline documentation


You can view Microsoft developer content online. This content is updated regularly.

You can also download and view the content locally in the offline Help Viewer. The
offline documentation is organized by books of related content, which are also updated
periodically. You can download the books you're interested in as they become available.
For more information, see Microsoft Help Viewer.

Many sections of the documentation are also available in PDF form. These sections have
a Download PDF link below the table of contents on Microsoft Learn.

Related sites
C++ Team Blog : Contains posts on various subjects by the experts on Microsoft's
C++ product team.

Shows: Contains video interviews and lectures. Select Browse all shows on the
Shows home page to find C++ content.
Visual Studio website : Contains articles and news about Visual Studio and related
development tools. This site also hosts Visual Studio downloads and
Redistributable files.

Microsoft Learn Q&A: Official Microsoft forums where you can post questions
about C++ and Visual Studio and get answers from Microsoft and from experts in
the community.

Visual Studio C++ Developer Community : Forums for reporting problems in the
C++ compiler and tools or the IDE, or for making product suggestions. You can
vote for your favorite ideas or bug reports, or add a new one. This site is
monitored by the development team.
How to report a problem with the
Microsoft C++ toolset or
documentation
Article • 03/02/2023

If you find problems in the Microsoft C++ compiler (MSVC), the linker, or other tools
and libraries, we want to know about them. When the issue is in our documentation, we
want to know about that, too.

How to report a C++ toolset issue


The best way to let us know about a problem is to send us a report that includes a
description of the problem you discovered. It should have all the details about how you
build your program. And it should include a repro, a complete test case we can use to
reproduce the problem on our own machines. This information lets us quickly verify that
the problem exists in our code and isn't local to your environment. It helps us determine
whether it affects other versions of the compiler, and to diagnose its cause.

In the following sections, read about what makes a good report. We describe how to
generate a repro for the kind of issue you found, and how to send your report to the
product team. Your reports are important to us and to other developers like you. Thank
you for helping us improve Microsoft C++!

How to prepare your report


It's important to create a high-quality report, because it's difficult for us to reproduce
the problem you found without complete information. The better your report is, the
more effectively we can recreate and diagnose the problem.

At a minimum, your report should contain:

The full version information of the toolset you're using.

The full cl.exe command line used to build your code.

A detailed description of the problem you found.

A repro: a complete, simplified, self-contained source code example that


demonstrates the problem.
Read on to learn more about the specific information we need and where you can find
it, and how to create a good repro.

The toolset version


We need the full version information and the target architecture of the toolset that
causes the problem. That's so we can test your repro against the same toolset on our
machines. If we can reproduce the problem, this information also gives us a starting
point to investigate which other versions of the toolset have the same problem.

To report the full version of your compiler

1. Open the Developer Command Prompt that matches the Visual Studio version
and configuration architecture used to build your project. For example, if you build
by using Visual Studio 2017 on x64 for x64 targets, choose x64 Native Tools
Command Prompt for VS 2017. For more information, see Developer command
prompt shortcuts.

2. In the developer command prompt console window, enter the command cl /Bv.

The output should look similar to:

Output

C:\Users\username\Source>cl /Bv
Microsoft (R) C/C++ Optimizing Compiler Version 19.14.26428.1 for x86
Copyright (C) Microsoft Corporation. All rights reserved.

Compiler Passes:
C:\Program Files (x86)\Microsoft Visual
Studio\2017\Enterprise\VC\Tools\MSVC\14.14.26428\bin\HostX86\x86\cl.exe:
Version 19.14.26428.1
C:\Program Files (x86)\Microsoft Visual
Studio\2017\Enterprise\VC\Tools\MSVC\14.14.26428\bin\HostX86\x86\c1.dll:
Version 19.14.26428.1
C:\Program Files (x86)\Microsoft Visual
Studio\2017\Enterprise\VC\Tools\MSVC\14.14.26428\bin\HostX86\x86\c1xx.dll:
Version 19.14.26428.1
C:\Program Files (x86)\Microsoft Visual
Studio\2017\Enterprise\VC\Tools\MSVC\14.14.26428\bin\HostX86\x86\c2.dll:
Version 19.14.26428.1
C:\Program Files (x86)\Microsoft Visual
Studio\2017\Enterprise\VC\Tools\MSVC\14.14.26428\bin\HostX86\x86\link.exe:
Version 14.14.26428.1
C:\Program Files (x86)\Microsoft Visual
Studio\2017\Enterprise\VC\Tools\MSVC\14.14.26428\bin\HostX86\x86\mspdb140.dl
l: Version 14.14.26428.1
C:\Program Files (x86)\Microsoft Visual
Studio\2017\Enterprise\VC\Tools\MSVC\14.14.26428\bin\HostX86\x86\1033\clui.d
ll: Version 19.14.26428.1

cl : Command line error D8003 : missing source filename

Copy and paste the entire output into your report.

The command line


We need the exact command line, cl.exe and all of its arguments, used to build your
code. That's so we can build it in exactly the same way on our machines. It's important
because the problem you found might only exist when building with a certain argument
or combination of arguments.

The best place to find this information is in the build log immediately after you
experience the problem. It ensures that the command line contains exactly the same
arguments that might contribute to the problem.

To report the contents of the command line


1. Locate the CL.command.1.tlog file and open it. By default, this file is located in
your Documents folder in \Visual Studio
version\Projects\SolutionName\ProjectName\Configuration\ProjectName.tlog\CL.co
mmand.1.tlog, or in your User folder under
\Source\Repos\SolutionName\ProjectName\Configuration\ProjectName.tlog\CL.co
mmand.1.tlog. It may be in a different location if you use another build system, or
if you changed the default location for your project.

Inside this file, find the names of your source code files, followed by the command-
line arguments used to compile them, each on separate lines.

2. Locate the line that contains the name of the source code file where the problem
occurs. The line below it contains the corresponding cl.exe command arguments.

Copy and paste the entire command line into your report.

A description of the problem


We need a detailed description of the problem you found. That's so we can verify that
we see the same effect on our machines. It's also sometimes useful for us to know what
you were trying to accomplish, and what you expected to happen.
A good description provides the exact error messages given by the toolset, or the exact
runtime behavior you see. We need this information to verify that we properly
reproduced the issue. Include all of the compiler output, not just the last error message.
We need to see everything that led up to the issue you report. If you can duplicate the
issue by using the command-line compiler, that compiler output is preferred. The IDE
and other build systems may filter the error messages you see, or only capture the first
line of an error message.

If the issue is that the compiler accepts invalid code and doesn't generate a diagnostic,
include that in your report.

To report a runtime behavior problem, include an exact copy of what the program
prints, and what you expect to see. Ideally, embed it in the output statement itself, for
example, printf("This should be 5: %d\n", actual_result); . If your program crashes
or hangs, mention that as well.

Add any other details that might help us diagnose the problem you found, such as any
work-arounds you discovered. Try not to repeat information found elsewhere in your
report.

The repro
A repro is a complete, self-contained source code example. It reproducibly demonstrates
the problem you found, hence the name. We need a repro so that we can reproduce the
error on our machines. The code should be sufficient by itself to create a basic
executable that compiles and runs. Or, that would compile and run, if not for the
problem you found. A repro isn't a code snippet. It should have complete functions and
classes, and contain all the necessary #include directives, even for the standard headers.

What makes a good repro


A good repro is:

Minimal. Repros should be as small as possible yet still demonstrate exactly the
problem you found. Repros don't need to be complex or realistic. They only need
to show code that conforms to the Standard, or to the documented compiler
implementation. For a missing diagnostic, your repro should show the code that's
not conformant. Simple, to-the-point repros that contain only enough code to
demonstrate the problem are best. If you can eliminate or simplify the code and
remain conformant, and also leave the issue unchanged, then do so. You don't
need to include counter-examples of code that works.
Self-Contained. Repros should avoid unnecessary dependencies. If you can
reproduce the problem without third-party libraries, then do so. If you can
reproduce the problem without any library code besides simple output statements
(for example, puts("this shouldn't compile"); , std::cout << value; , and
printf("%d\n", value); ), then do so. It's ideal if the example can be condensed to

a single source code file, without reference to any user headers. Reducing the
amount of code we have to consider as a possible contributor to the problem is
enormously helpful to us.

Against the latest compiler version. Repros should use the most recent update to
the latest version of the toolset whenever possible. Or, use the most recent
prerelease version of the next update or next major release. Problems you may find
in older versions of the toolset are often fixed in newer versions. Fixes are
backported to older versions only in exceptional circumstances.

Checked against other compilers if relevant. Repros that involve portable C++
code should verify behavior against other compilers if possible. The C++ standard
ultimately determines program correctness, and no compiler is perfect. However,
when Clang and GCC accept your code without a diagnostic, and MSVC doesn't,
you probably found a bug in our compiler. (Other possibilities include differences
in Unix and Windows behavior, or different levels of C++ standards
implementation, and so on.) When all the compilers reject your code, then it's
likely that your code is incorrect. Seeing different error messages may help you
diagnose the issue yourself.

You can find lists of online compilers to test your code against in Online C++
compilers on the ISO C++ website, or this curated List of Online C++
Compilers on GitHub. Some specific examples include Wandbox and Compiler
Explorer .

7 Note

The online compiler websites are not affiliated with Microsoft. Many online
compiler websites are run as personal projects. Some of these sites may be
unavailable when you read this, but a search should find others you can use.

Problems in the compiler, linker, and in the libraries, tend to show themselves in
particular ways. The kind of problem you find will determine what kind of repro you
should include in your report. Without an appropriate repro, we have nothing to
investigate. Here are a few of the kinds of issues that you may see. We include
instructions on how to generate the kind of repro you should use to report each kind of
problem.

Frontend (parser) crash

Frontend crashes occur during the parsing phase of the compiler. Typically, the compiler
emits Fatal Error C1001, and references the source code file and line number on which
the error occurred. It often mentions a file named msc1.cpp, but you can ignore this
detail.

For this kind of crash, provide a Preprocessed repro.

Here's example compiler output for this kind of crash:

Output

SandBoxHost.cpp
d:\o\dev\search\foundation\common\tools\sandbox\managed\managed.h(929):
fatal error C1001: An internal error has occurred in the compiler.
(compiler file 'msc1.cpp', line 1369)
To work around this problem, try simplifying or changing the program near
the
locations listed above.
Please choose the Technical Support command on the Visual C++
Help menu, or open the Technical Support help file for more information
d:\o\dev\search\foundation\common\tools\sandbox\managed\managed.h(929):
note: This diagnostic occurred in the compiler generated function
'void
Microsoft::Ceres::Common::Tools::Sandbox::SandBoxedProcess::Dispose(bool)'
Internal Compiler Error in d:\o\dev\otools\bin\x64\cl.exe. You will be
prompted
to send an error report to Microsoft later.
INTERNAL COMPILER ERROR in 'd:\o\dev\otools\bin\x64\cl.exe'
Please choose the Technical Support command on the Visual C++
Help menu, or open the Technical Support help file for more information

Backend (code generation) crash


Backend crashes occur during the code generation phase of the compiler. Typically, the
compiler emits Fatal Error C1001, and it might not reference the source code file and
line number associated with the problem. It often mentions the file
compiler\utc\src\p2\main.c, but you can ignore this detail.

For this kind of crash, provide a Link repro if you're using Link-Time Code Generation
(LTCG), enabled by the /GL command-line argument to cl.exe. If not, provide a
Preprocessed repro instead.
Here's example compiler output for a backend crash in which LTCG isn't used. If your
compiler output looks like the following, you should provide a Preprocessed repro.

Output

repro.cpp
\\officefile\public\tadg\vc14\comperror\repro.cpp(13) : fatal error C1001:
An internal error has occurred in the compiler.
(compiler file 'f:\dd\vctools\compiler\utc\src\p2\main.c', line 230)
To work around this problem, try simplifying or changing the program near
the
locations listed above.
Please choose the Technical Support command on the Visual C++
Help menu, or open the Technical Support help file for more information
INTERNAL COMPILER ERROR in
'C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\cl.exe'
Please choose the Technical Support command on the Visual C++
Help menu, or open the Technical Support help file for more information

If the line that begins with INTERNAL COMPILER ERROR mentions link.exe, rather than
cl.exe, LTCG was enabled. Provide a Link repro in this case. When it's not clear whether
LTCG was enabled from the compiler error message, examine the command-line
arguments. You copied them from your build log, in a previous step for the /GL
command-line argument.

Linker crash
Linker crashes occur during the linking phase, after the compiler has run. Typically, the
linker emits Linker Tools Error LNK1000.

7 Note

If the output mentions C1001 or involves Link-Time Code Generation, refer to


Backend (code generation) crash instead.

For this kind of crash, provide a Link repro.

Here's an example of compiler output for this kind of crash:

Output

z:\foo.obj : error LNK1000: Internal error during IMAGE::Pass2

Version 14.00.22816.0

ExceptionCode = C0000005
ExceptionFlags = 00000000
ExceptionAddress = 00007FF73C9ED0E6 (00007FF73C9E0000)
"z:\tools\bin\x64\link.exe"
NumberParameters = 00000002
ExceptionInformation[ 0] = 0000000000000000
ExceptionInformation[ 1] = FFFFFFFFFFFFFFFF

CONTEXT:

Rax = 0000000000000400 R8 = 0000000000000000


Rbx = 000000655DF82580 R9 = 00007FF840D2E490
Rcx = 005C006B006F006F R10 = 000000655F97E690
Rdx = 000000655F97E270 R11 = 0000000000000400
Rsp = 000000655F97E248 R12 = 0000000000000000
Rbp = 000000655F97EFB0 E13 = 0000000000000000
Rsi = 000000655DF82580 R14 = 000000655F97F390
Rdi = 0000000000000000 R15 = 0000000000000000
Rip = 00007FF73C9ED0E6 EFlags = 0000000000010206
SegCs = 0000000000000033 SegDs = 000000000000002B
SegSs = 000000000000002B SegEs = 000000000000002B
SegFs = 0000000000000053 SegGs = 000000000000002B
Dr0 = 0000000000000000 Dr3 = 0000000000000000
Dr1 = 0000000000000000 Dr6 = 0000000000000000
Dr2 = 0000000000000000 Dr7 = 0000000000000000

If incremental linking is enabled, and the crash occurred only after a successful initial
link, that is, only after the first full link on which a later incremental link is based, also
provide a copy of the object (.obj) and library (.lib) files that correspond to source files
modified after the initial link was completed.

Bad code generation


Bad code generation is rare. It occurs when the compiler mistakenly generates incorrect
code that causes your application to crash at runtime. Instead, it should generate correct
code, or detect a problem at compile time. If you believe the problem you found results
in bad code generation, treat your report the same as a Backend (code generation)
crash.

For this kind of crash, provide a Link repro if you're using the /GL command-line
argument to cl.exe. Provide a Preprocessed repro if not.

How to generate a repro


To help us track down the source of the problem, a good repro is vital. Before you do
any of the steps outlined below for specific kinds of repros, try to condense the code
that demonstrates the problem as much as possible. Try to eliminate or minimize
dependencies, required headers, and libraries. Limit the compiler options and
preprocessor definitions used, if possible.

Below are instructions for generating the various kinds of repros to use to report
different kinds of problems.

Preprocessed repros
A Preprocessed repro is a single source file that demonstrates a problem. It's generated
from the output of the C preprocessor. To create one, use the /P compiler option on the
original repro source file. This option inlines the included headers to remove
dependencies on other source and header files. The option also resolves macros, #ifdef
conditionals, and other preprocessor commands that could depend on your local
environment.

7 Note

Preprocessed repros are not as useful for problems that might be the result of bugs
in our standard library implementation, because we will often want to substitute
our latest, in-progress implementation to see whether we've already fixed the
problem. In this case, don't preprocess the repro, and if you can't reduce the
problem to a single source file, package your code into a .zip file or similar, or
consider using an IDE project repro. For more information, see Other repros.

To preprocess a source code file


1. Capture the command-line arguments used to build your repro, as described in To
report the contents of the command line.

2. Open the Developer Command Prompt that matches the Visual Studio version
and configuration architecture used to build your project.

3. Change to the directory that contains your repro project.

4. In the developer command prompt console window, enter the command cl /P


arguments filename.cpp. For arguments, use the list of arguments you captured
above. filename.cpp is the name of your repro source file. This command replicates
the command line you used for the repro, but stops the compilation after the
preprocessor pass. Then it writes the preprocessed source code to filename.i.

If you're preprocessing a C++/CX source code file, or you're using the C++ Modules
feature, some more steps are required. For more information, see the sections below.
After you generate the preprocessed file, it's a good idea to make sure that the problem
still repros when you compile the preprocessed file.

To confirm the preprocessed file still repros the error

1. In the developer command prompt console window, enter the command cl


arguments /TP filename.i to tell cl.exe to compile the preprocessed file as a C++
source file. The arguments are the same arguments captured above, but with any
/D and /I arguments removed. That's because they've already been included in the
preprocessed file. filename.i is the name of your preprocessed file.

2. Confirm that the problem is reproduced.

Finally, attach the preprocessed repro filename.i to your report.

Preprocessed C++/CX WinRT/UWP code repros


If you're using C++/CX to build your executable, there are some extra steps required to
create and validate a preprocessed repro.

To preprocess C++/CX source code


1. Create a preprocessed source file as described in To preprocess a source code file.

2. Search the generated filename.i file for #using directives.

3. Make a list of all of the referenced files. Leave out any Windows*.winmd files,
platform.winmd files, and mscorlib.dll.

To prepare to validate that the preprocessed file still reproduces the problem,

1. Create a new directory for the preprocessed file and copy it to the new directory.

2. Copy the .winmd files from your #using list to the new directory.

3. Create an empty vccorlib.h file in the new directory.

4. Edit the preprocessed file to remove any #using directives for mscorlib.dll.

5. Edit the preprocessed file to change any absolute paths to just the bare filenames
for the copied .winmd files.

Confirm that the preprocessed file still reproduces the problem, as above.
Preprocessed C++ Modules repros
If you're using the Modules feature of the C++ compiler, there are some different steps
required to create and validate a preprocessed repro.

To preprocess a source code file that uses a module

1. Capture the command-line arguments used to build your repro, as described in To


report the contents of the command line.

2. Open the Developer Command Prompt that matches the Visual Studio version
and configuration architecture used to build your project.

3. Change to the directory that contains your repro project.

4. In the developer command prompt console window, enter the command cl /P


arguments filename.cpp. The arguments are the arguments captured above, and
filename.cpp is the name of the source file that consumes the module.

5. Change to the directory that contains the repro project that built the module
interface (the .ifc output).

6. Capture the command-line arguments used to build your module interface.

7. In the developer command prompt console window, enter the command cl /P


arguments modulename.ixx. The arguments are the arguments captured above, and
modulename.ixx is the name of the file that creates the module interface.

After you generate the preprocessed files, it's a good idea to make sure the problem still
repros when you use the preprocessed file.

To confirm the preprocessed file still repros the error

1. In the developer console window, change back to the directory that contains your
repro project.

2. Enter the command cl arguments /TP filename.i as above, to compile the


preprocessed file as if it were a C++ source file.

3. Confirm that the problem is still reproduced by the preprocessed file.

Finally, attach the preprocessed repro files (filename.i and modulename.i) along with the
.ifc output to your report.
Link repros
A link repro is the linker-generated contents of a directory, specified either by the
link_repro environment variable, or as an argument to the /LINKREPRO linker option. It
contains build artifacts that collectively demonstrate a problem that occurs at link time.
Examples include a backend crash involving Link-Time Code Generation (LTCG), or a
linker crash. These build artifacts are the ones needed as linker input so the problem can
be reproduced. A link repro can be created easily by using this environment variable. It
enables the linker's built-in repro generation capability.

To generate a link repro using the link_repro environment variable

1. Capture the command-line arguments used to build your repro, as described in To


report the contents of the command line.

2. Open the Developer Command Prompt that matches the Visual Studio version
and configuration architecture used to build your project.

3. In the developer command prompt console window, change to the directory that
contains your repro project.

4. Enter mkdir linkrepro to create a directory named linkrepro for the link repro. You
can use a different name to capture another link repro.

5. Enter the command set link_repro=linkrepro to set the link_repro environment


variable to the directory you created. If your build is run from a different directory,
as is often the case for more complex projects, then set link_repro to the full path
to your link repro directory instead.

6. To build the repro project in Visual Studio, in the developer command prompt
console window, enter the command devenv. It ensures that the value of the
link_repro environment variable is visible to Visual Studio. To build the project at
the command line, use the command-line arguments captured above to duplicate
the repro build.

7. Build your repro project, and confirm that the expected problem occurred.

8. Close Visual Studio, if you used it to do the build.

9. In the developer command prompt console window, enter the command set
link_repro= to clear the link_repro environment variable.

Finally, package the repro by compressing the entire linkrepro directory into a .zip file or
similar, and attach it to your report.
The /LINKREPRO linker option has the same effect as the link_repro environment
variable. You can use the /LINKREPROTARGET option to specify the name to filter on for
the generated link repro. To use /LINKREPROTARGET, you must also specify the /OUT
linker option.

To generate a link repro using the /LINKREPRO option

1. Create a directory to hold the link repro. We'll refer to the full directory path you
create as directory-path. Use double quotes around the path if it includes spaces.

2. Add the /LINKREPRO:directory-path command to the linker command line. In


Visual Studio, open the Property Pages dialog for your project. Select the
Configuration Properties > Linker > Command Line property page. Then, enter
the /LINKREPRO:directory-path option in the Additional Options box. Choose OK
to save your changes.

3. Build your repro project, and confirm that the expected problem has occurred.

Finally, package the repro by compressing the entire directory-path link repro directory
into a .zip file or similar, and attach it to your report.

Other repros
If you can't reduce the problem to a single source file or preprocessed repro, and the
problem doesn't require a link repro, we can investigate an IDE project. All the guidance
on how to create a good repro still applies: The code ought to be minimal and self-
contained. The problem should occur in our most recent tools, and if relevant, shouldn't
be seen in other compilers.

Create your repro as a minimal IDE project, then package it by compressing the entire
directory structure into a .zip file or similar and attach it to your report.

Ways to send your report


You have a couple of good ways to get your report to us. You can use Visual Studio's
built-in problem reporting tool or the Visual Studio Developer Community page.
There's also a Product feedback button at the bottom of this page. The choice depends
on whether you want to use the built-in tools in the IDE to capture screenshots and
organize your report. If you prefer not to, you can use the Developer Community
website directly.
7 Note

Regardless of how you submit your report, Microsoft respects your privacy.
Microsoft is committed to compliance with all data privacy laws and regulations.
For information about how we treat the data that you send us, see the Microsoft
Privacy Statement .

Use the Report a Problem tool


The Report a Problem tool in Visual Studio is a way for Visual Studio users to report
problems with just a few clicks. It pops up a simple form to send detailed information
about the problem you found. You can then submit your report without ever leaving the
IDE.

Reporting your problem through the Report a Problem tool is easy and convenient
from the IDE. You can access it from the title bar by choosing the Send Feedback icon
next to the Quick Launch search box. Or, you can find it on the menu bar in Help >
Send Feedback > Report a Problem.

When you choose to report a problem, first search the Developer Community for similar
problems. In case your problem has been reported before, upvote the report and add
comments with more specifics. If you don't see a similar problem, choose the Report
new problem button at the bottom of the Visual Studio Feedback dialog and follow the
steps to report your problem.

Use the Visual Studio Developer Community pages


The Visual Studio Developer Community pages are another convenient way to report
problems and find solutions for Visual Studio and the C++ compiler, tools, and libraries.
There are specific Developer Community pages for Visual Studio , Visual Studio for
Mac , .NET , C++ , Azure DevOps , and Azure DevOps Server .

Beneath the community tabs, near the top of each page, is a search box. You can use it
to find posts that report problems similar to yours. You may find a solution or other
useful information related to your problem is already available. If someone has reported
the same problem before, then upvote and comment on that report, rather than create
a new problem report. To comment, vote, or report a new problem, you may be asked to
sign in to your Visual Studio account. The first time you sign in, you have to agree to
give the Developer Community app access to your profile.
For issues with the C++ compiler, linker, and other tools and libraries, first search the
C++ Developer Community page. If you search for your problem, and it isn't already
reported, choose the Report a problem button next to the search box. You can include
your repro code and command line, screenshots, links to related discussions, and any
other information you think is relevant and useful.

 Tip

Information in the initial Developer Community report will always be public. If this
is a concern, see the next section about Reports and privacy.

 Tip

For other kinds of problems you might find in Visual Studio that are unrelated to
the C++ toolset (For example, UI issues, broken IDE functionality, or general
crashes), use the Report a Problem tool in the IDE. This is the best choice, due to
its screenshot capabilities and its ability to record UI actions that lead to the
problem you found. These kinds of errors can also be looked up on the Visual
Studio Developer Community site. For more information, see How to report a
problem with Visual Studio.

Reports and privacy


All information in reports and any comments and replies are publicly visible by
default. Normally, it's a benefit, because it allows the entire community to see the
issues, solutions, and workarounds other users have found. However, if you're
concerned about making your data or identity public, for privacy or intellectual property
reasons, you have options.

If you're concerned about revealing your identity, create a new Microsoft account that
doesn't disclose any details about you. Use this account to create your report.

Don't put anything you want to keep private in the title or content of the initial
report, which is public. Instead, say that you'll send details privately in a separate
comment. To make sure that your report is directed to the right people, include
cppcompiler in the topic list of your problem report. Once the problem report is
created, it's now possible to specify who can see your replies and attachments.

To create a problem report for private information


1. In the report you created, choose Add comment to create your private description
of the problem.

2. In the reply editor, use the dropdown control below the Submit and Cancel
buttons to specify the audience for your reply. Only the people you specify can see
these private replies and any images, links, or code you include in them. Choose
Viewable by moderators and the original poster to limit visibility to Microsoft
employees and yourself.

3. Add the description and any other information, images, and file attachments
needed for your repro. Choose the Submit button to send this information
privately.

There's a 2GB limit on attached files, and a maximum of 10 files. For any larger
uploads, request an upload URL in your private comment.

Any replies under this comment have the same restricted visibility you specified. It's true
even if the dropdown control on replies doesn't show the restricted visibility status
correctly.

To maintain your privacy and keep your sensitive information out of public view, be
careful. Keep all interaction with Microsoft to replies under the restricted comment.
Replies to other comments may cause you to accidentally disclose sensitive information.

How to report a C++ documentation issue


We use GitHub issues to track problems reported in our documentation. You can now
create GitHub issues directly from a content page, which enables you interact in a richer
way with writers and product teams. If you see an issue with a document, a bad code
sample, a confusing explanation, a critical omission, or even just a typo, you can easily
let us know. Scroll to the bottom of the page and select Sign in to give documentation
feedback. You need to create a GitHub account if you don't have one already. When you
have a GitHub account, you can see all of our documentation issues and their status.
You also get notifications when changes are made for the issue you reported. For more
information, see our Feedback System blog entry.

You create a documentation issue on GitHub when you use the documentation
feedback button. The issue is automatically filled in with some information about the
page you created the issue on. That's how we know where the problem is located, so
don't edit this information. Just append the details about what's wrong, and if you like, a
suggested fix. Our C++ docs are open source , so if you'd like to submit a fix yourself,
you can. For more information about how you can contribute to our documentation, see
our Contributing guide on GitHub.

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Install C and C++ support in Visual
Studio
Article • 12/09/2021

If you haven't downloaded and installed Visual Studio and the Microsoft C/C++ tools
yet, here's how to get started.

Visual Studio 2022 Installation


Welcome to Visual Studio 2022! In this version, it's easy to choose and install just the
features you need. And because of its reduced minimum footprint, it installs quickly and
with less system impact.

7 Note

This topic applies to installation of Visual Studio on Windows. Visual Studio Code
is a lightweight, cross-platform development environment that runs on Windows,
Mac, and Linux systems. The Microsoft C/C++ for Visual Studio Code extension
supports IntelliSense, debugging, code formatting, auto-completion. Visual Studio
for Mac doesn't support Microsoft C++, but does support .NET languages and
cross-platform development. For installation instructions, see Install Visual Studio
for Mac.

Want to know more about what else is new in this version? See the Visual Studio release
notes.

Ready to install? We'll walk you through it, step-by-step.

Step 1 - Make sure your computer is ready for Visual


Studio
Before you begin installing Visual Studio:

1. Check the system requirements. These requirements help you know whether your
computer supports Visual Studio 2022.

2. Apply the latest Windows updates. These updates ensure that your computer has
both the latest security updates and the required system components for Visual
Studio.
3. Reboot. The reboot ensures that any pending installs or updates don't hinder the
Visual Studio install.

4. Free up space. Remove unneeded files and applications from your %SystemDrive%
by, for example, running the Disk Cleanup app.

For questions about running previous versions of Visual Studio side by side with Visual
Studio 2022, see the Visual Studio 2022 Platform Targeting and Compatibility page.

Step 2 - Download Visual Studio


Next, download the Visual Studio bootstrapper file. To do so, choose the following
button to go to the Visual Studio download page. Select the edition of Visual Studio that
you want and choose the Free trial or Free download button.

Download Visual Studio

Step 3 - Install the Visual Studio installer


Run the bootstrapper file you downloaded to install the Visual Studio Installer. This new
lightweight installer includes everything you need to both install and customize Visual
Studio.

1. From your Downloads folder, double-click the bootstrapper that matches or is


similar to one of the following files:

vs_community.exe for Visual Studio Community


vs_professional.exe for Visual Studio Professional
vs_enterprise.exe for Visual Studio Enterprise

If you receive a User Account Control notice, choose Yes to allow the bootstrapper
to run.

2. We'll ask you to acknowledge the Microsoft License Terms and the Microsoft
Privacy Statement . Choose Continue.

Step 4 - Choose workloads


After the installer is installed, you can use it to customize your installation by selecting
the workloads, or feature sets, that you want. Here's how.

1. Find the workload you want in the Installing Visual Studio screen.
For core C and C++ support, choose the "Desktop development with C++"
workload. It comes with the default core editor, which includes basic code editing
support for over 20 languages, the ability to open and edit code from any folder
without requiring a project, and integrated source code control.

Additional workloads support other kinds of development. For example, choose


the "Universal Windows Platform development" workload to create apps that use
the Windows Runtime for the Microsoft Store. Choose "Game development with
C++" to create games that use DirectX, Unreal, and Cocos2d. Choose "Linux
development with C++" to target Linux platforms, including IoT development.

The Installation details pane lists the included and optional components installed
by each workload. You can select or deselect optional components in this list. For
example, to support development by using the Visual Studio 2017 or 2015
compiler toolsets, choose the MSVC v141 or MSVC v140 optional components. You
can add support for MFC, the experimental Modules language extension,
IncrediBuild, and more.

2. After you choose the workload(s) and optional components you want, choose
Install.

Next, status screens appear that show the progress of your Visual Studio
installation.

 Tip

At any time after installation, you can install workloads or components that you
didn't install initially. If you have Visual Studio open, go to Tools > Get Tools and
Features... which opens the Visual Studio Installer. Or, open Visual Studio Installer
from the Start menu. From there, you can choose the workloads or components
that you wish to install. Then, choose Modify.

Step 5 - Choose individual components (Optional)


If you don't want to use the Workloads feature to customize your Visual Studio
installation, or you want to add more components than a workload installs, you can do
so by installing or adding individual components from the Individual components tab.
Choose what you want, and then follow the prompts.

Step 6 - Install language packs (Optional)


By default, the installer program tries to match the language of the operating system
when it runs for the first time. To install Visual Studio in a language of your choosing,
choose the Language packs tab from the Visual Studio Installer, and then follow the
prompts.

Change the installer language from the command line

Another way that you can change the default language is by running the installer from
the command line. For example, you can force the installer to run in English by using the
following command: vs_installer.exe --locale en-US . The installer will remember this
setting when it's run the next time. The installer supports the following language tokens:
zh-cn, zh-tw, cs-cz, en-us, es-es, fr-fr, de-de, it-it, ja-jp, ko-kr, pl-pl, pt-br, ru-ru, and tr-tr.
Step 7 - Change the installation location (Optional)
You can reduce the installation footprint of Visual Studio on your system drive. You can
choose to move the download cache, shared components, SDKs, and tools to different
drives, and keep Visual Studio on the drive that runs it the fastest.

) Important

You can select a different drive only when you first install Visual Studio. If you've
already installed it and want to change drives, you must uninstall Visual Studio and
then reinstall it.

Step 8 - Start developing


1. After Visual Studio installation is complete, choose the Launch button to get
started developing with Visual Studio.

2. On the start window, choose Create a new project.

3. In the search box, enter the type of app you want to create to see a list of available
templates. The list of templates depends on the workload(s) that you chose during
installation. To see different templates, choose different workloads.

You can also filter your search for a specific programming language by using the
Language drop-down list. You can filter by using the Platform list and the Project
type list, too.

4. Visual Studio opens your new project, and you're ready to code!

When Visual Studio is running, you're ready to continue to the next step.

Next Steps
Create a C++ project
Create a C++ console app project
Article • 07/06/2023

The usual starting point for a C++ programmer is a "Hello, world!" application that runs
on the command line. That's what you create in Visual Studio in this step.

Prerequisites
Have Visual Studio with the Desktop development with C++ workload installed
and running on your computer. If it's not installed yet, see Install C++ support in
Visual Studio.

Create your app project


Visual Studio uses projects to organize the code for an app, and solutions to organize
your projects. A project contains all the options, configurations, and rules used to build
your apps. It manages the relationship between all the project's files and any external
files. To create your app, first, create a new project and solution.

1. In Visual Studio, open the File menu and choose New > Project to open the Create
a new Project dialog. Select the Console App template that has C++, Windows,
and Console tags, and then choose Next.
2. In the Configure your new project dialog, enter HelloWorld in the Project name
edit box. Choose Create to create the project.

Visual Studio creates a new project. It's ready for you to add and edit your source
code. By default, the Console App template provides source code for a "Hello
World" app, like this:

When the code looks like this in the editor, you're ready to go on to the next step
and build your app.
I ran into a problem.

Next steps
Build and run a C++ project

Troubleshooting guide
Come here for solutions to common issues when you create your first C++ project.

Create your app project: issues


The New Project dialog should show a Console App template that has C++, Windows,
and Console tags. If you don't see it, there are two possible causes. It might be filtered
out of the list, or it might not be installed. First, check the filter dropdowns at the top of
the list of templates. Set them to C++, Windows, and Console. The C++ Console App
template should appear; otherwise, the Desktop development with C++ workload isn't
installed.

To install Desktop development with C++, you can run the installer right from the New
Project dialog. Choose the Install more tools and features link at the bottom of the
template list to start the installer. If the User Account Control dialog requests
permissions, choose Yes. In the installer, make sure the Desktop development with C++
workload is checked. Then choose Modify to update your Visual Studio installation.

If another project with the same name already exists, choose another name for your
project. Or, delete the existing project and try again. To delete an existing project, delete
the solution folder (the folder that contains the helloworld.sln file) in File Explorer.

Go back.
Build and run a C++ console app
project
Article • 07/01/2024

In Create a C++ console app project you created a C++ console app project and
entered your code. Now you can build and run it within Visual Studio. Then, run it as a
stand-alone app from the command line.

Prerequisites
Have Visual Studio with the Desktop development with C++ workload installed
and running on your computer. If it's not installed, follow the steps in Install C++
support in Visual Studio.
Create a "Hello, World!" project. By default, it contains code to print Hello World! .
If you haven't done this step yet, follow the steps in Create a C++ console app
project.

If Visual Studio looks like this, you're ready to build and run your app:

Build and run your code in Visual Studio


1. To build your project, from the main menu choose Build > Build Solution. The
Output window shows the results of the build process.

2. To run the code, on the menu bar, choose Debug, Start without debugging.

A console window opens and then runs your app. When you start a console app in
Visual Studio, it runs your code, then prints "Press any key to continue . . ." to give
you a chance to see the output.
Congratulations! You created your first "Hello, world!" console app in Visual Studio!
Press a key to dismiss the console window and return to Visual Studio.

I ran into a problem.

Run your code in a command window


Normally, you run console apps at the command prompt, not in Visual Studio. Once
Visual Studio builds your app, you can run it from a command window. Here's how to
find and run your new app in a command prompt window.

1. In Solution Explorer, select the HelloWorld solution (not the HelloWorld project)
and right-click to open the context menu. Choose Open Folder in File Explorer to
open a File Explorer window in the HelloWorld solution folder.

2. In the File Explorer window, open the x64 folder and then the Debug folder. This
folder contains your app, HelloWorld.exe , and debugging files. Hold down the
Shift key and right-click on HelloWorld.exe to open the context menu. Choose
Copy as path to copy the path to your app to the clipboard. If you see
HelloWorld.exe.recipe , it's because you did the Open Folder in File Explorer step

on the HelloWorld project instead of the HelloWorld solution. Navigate up a level in


File Explorer to get to the solution folder. This folder also contains a x64\Debug\
folder, where HelloWorld.exe is.

3. To open a command prompt window, press Windows+R to open the Run dialog.
Enter cmd.exe in the Open textbox, then choose OK to run a command prompt
window.

4. In the command prompt window, right-click to paste the path to your app into the
command prompt. Press Enter to run your app.
Congratulations, you built and ran a console app in Visual Studio!

I ran into a problem.

Next Steps
Once you build and run this simple app, you're ready for more complex projects. For
more information, see Using the Visual Studio IDE for C++ Desktop Development. It has
more detailed walkthroughs that explore the capabilities of Microsoft C++ in Visual
Studio.

Troubleshooting guide
Come here for solutions to common issues when you create your first C++ project.

Build and run your code in Visual Studio: issues


If red squiggles appear under anything in the source code editor, the build may have
errors or warnings. Check that your code matches the example in spelling, punctuation,
and case.

Go back.

Run your code in a command window: issues


If the path shown in File Explorer ends in \HelloWorld\HelloWorld , you opened the
HelloWorld project instead of the HelloWorld solution. You won't see your app in the
x64\Debug folder. Navigate up a level in File Explorer to get to the solution folder, the

first HelloWorld in the path. This folder also contains a x64\Debug folder, where your
app is.

You can also navigate to the solution x64\Debug folder at the command line to run your
app. Your app won't run from other directories without specifying the path to the app.
However, you can copy your app to another directory and run it from there. It's also
possible to copy it to a directory specified by your PATH environment variable, then run
it from anywhere.

If you don't see Copy as path in the shortcut menu, dismiss the menu, and then hold
down the Shift key while you open it again. This command is just for convenience. You
can also copy the path to the folder from the File Explorer search bar, and paste it into
the Run dialog, and then enter the name of your executable at the end. It's just a little
more typing, but it has the same result.

Go back.

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Create a console calculator in C++
Article • 03/22/2024

The usual starting point for a C++ programmer is a "Hello, world!" application that runs
on the command line. You'll start with that in this article, and then we move on to
something more challenging: a calculator app.

Prerequisites
Visual Studio with the Desktop development with C++ workload installed and
running on your computer. To install it, see Install C++ support in Visual Studio.
This tutorial demonstrates a feature called edit and continue which allows you to
make changes to your code while the app is running. To enable edit and continue,
from the main menu select Tools > Options > Debugging > General and ensure
that Require source files to exactly match the original version is checked.

Create your app project


Visual Studio uses projects to organize the code for an app, and solutions to organize
one or more projects. A project contains all the options, configurations, and rules used
to build an app. It also manages the relationship between all the project's files and any
external files. To create your app, first, create a new project and solution.

1. Start Visual Studio--the Visual Studio Start dialog box appears. Select Create a new
project to get started.
2. In the list of project templates, select Console App, then select Next.

) Important

Make sure you select the C++ version of the Console App template. It has the
C++, Windows, and Console tags, and the icon has "++" in the corner.
3. In the Configure your new project dialog box, select the Project name text box,
name your new project CalculatorTutorial, then select Create.

An empty C++ Windows console application 'Hello World' app is created. Console
applications use a Windows console window to display output and accept user
input. In Visual Studio, an editor window opens and shows the generated code:

C++

// CalculatorTutorial.cpp : This file contains the 'main' function.


Program execution begins and ends there.
//

#include <iostream>

int main()
{
std::cout << "Hello World!\n";
}

// Run program: Ctrl + F5 or Debug > Start Without Debugging menu


// Debug program: F5 or Debug > Start Debugging menu

// Tips for Getting Started:


// 1. Use the Solution Explorer window to add/manage files
// 2. Use the Team Explorer window to connect to source control
// 3. Use the Output window to see build output and other messages
// 4. Use the Error List window to view errors
// 5. Go to Project > Add New Item to create new code files, or
Project > Add Existing Item to add existing code files to the project
// 6. In the future, to open this project again, go to File > Open >
Project and select the .sln file

Verify that your new app builds and runs


The template for a new Windows console application creates a simple C++ "Hello
World" app. At this point, you can see how Visual Studio builds and runs the apps you
create right from the IDE.

1. To build your project, select Build Solution from the Build menu. The Output
window shows the results of the build process.

2. To run the code, on the menu bar, select Debug, Start without debugging
(Ctrl+F5).
A console window opens and then runs your app.

When you start a console app in Visual Studio, it runs your code, then prints "Press
any key to close this window . . ." to give you a chance to see the output.

Congratulations! You created your first "Hello, world!" console app in Visual Studio!

3. Press a key to dismiss the console window and return to Visual Studio.

You now have the tools to build and run your app after every change, to verify that the
code still works as you expect. Later, we show you how to debug it if it doesn't.

Edit the code


Now let's modify the code in this template to be a calculator app.

1. Replace the contents of the CalculatorTutorial.cpp file with the following code so
that it matches this example:

C++

// CalculatorTutorial.cpp : This file contains the 'main' function.


Program execution begins and ends there.
//

#include <iostream>

using namespace std;

int main()
{
cout << "Calculator Console Application" << endl << endl;
cout << "Please enter the operation to perform. Format: a+b | a-b |
a*b | a/b"
<< endl;
return 0;
}

// Run program: Ctrl + F5 or Debug > Start Without Debugging menu


// Debug program: F5 or Debug > Start Debugging menu
// Tips for Getting Started:
// 1. Use the Solution Explorer window to add/manage files
// 2. Use the Team Explorer window to connect to source control
// 3. Use the Output window to see build output and other messages
// 4. Use the Error List window to view errors
// 5. Go to Project > Add New Item to create new code files, or
Project > Add Existing Item to add existing code files to the project
// 6. In the future, to open this project again, go to File > Open >
Project and select the .sln file

Understanding the code:

The #include statements allow you to reference code located in other


files. Sometimes, you may see a filename surrounded by angle brackets
(<>); other times, it's surrounded by quotes (" "). In general, angle
brackets are used when referencing the C++ Standard Library, while
quotes are used for other files.
The using namespace std; line tells the compiler to expect stuff from the
C++ Standard Library to be used in this file. Without this line, each
keyword from the library would have to be preceded with std:: to
denote its scope. For instance, without that line, each reference to cout
would have to be written as std::cout . The using statement is added to
make the code look more clean.
The cout keyword is used to print to standard output in C++. The <<
operator tells the compiler to send whatever is to the right of it to the
standard output.
The endl keyword is like the Enter key; it ends the line and moves the
cursor to the next line. It's a better practice to put a \n inside the string
(contained by "" ) to do the same thing because endl always flushes the
buffer which can hurt the performance of the program. But since this is a
very small app, endl is used instead for better readability.
All C++ statements must end with semicolons and all C++ applications
must contain a main() function. This function is what the program runs at
the start. All code must be accessible from main() in order to be used.

2. To save the file, press Ctrl+S, or select the Save icon near the top of the IDE, the
floppy disk icon in the toolbar under the menu bar.
3. To run the application, press Ctrl+F5 or go to the Debug menu and select Start
Without Debugging. You should see a console window appear that displays the
text specified in the code.

4. Close the console window when you're done.

Add code to do some math


A class is like a blueprint for an object that does something. In this case, we define a
calculator class to contain the math logic.

Add a Calculator class


1. Go to the Project menu and select Add Class. In the Class Name edit box, enter
Calculator. Select OK.

Two new files get added to your project. To save all your changed files at once,
press Ctrl+Shift+S. It's a keyboard shortcut for File > Save All. There's also a
toolbar button for Save All, an icon of two floppy disks, found beside the Save
button. In general, it's good practice to do Save All frequently, so you don't miss
any files when you save.
The Add Class wizard creates .h and .cpp files that have the same name as the
class. You can see a full list of your project files in the Solution Explorer window,
visible on the side of the IDE. If the window isn't visible, you can open it from the
menu bar: select View > Solution Explorer.

You can open a file by double-clicking it in the Solution Explorer window. Double-
click Calculator.h to open it.

2. Replace the contents of Calculator.h with the following code so that the file now
looks like this:

C++

#pragma once
class Calculator
{
public:
double Calculate(double x, char oper, double y);
};

Understanding the code

This code declares a new function called Calculate , which we use to run
math operations for addition, subtraction, multiplication, and division.
C++ code is organized into header ( .h ) files and source ( .cpp ) files.
Several other file extensions are supported by various compilers, but
these are the main ones to know about. Functions and variables are
normally declared, that is, given a name and a type, in header files, and
implemented, or given a definition, in source files. To access code defined
in another file, you can use #include "filename.h" , where filename.h is
the name of the file that declares the variables or functions you want to
use.
It's good practice to organize your code into different files based on what
it does, so it's easy to find the code you need later. In our case, we define
the Calculator class separately from the file containing the main()
function, but we plan to reference the Calculator class in main() .

3. A green squiggle appears under Calculate because although the Calculate


function is declared, it isn't defined. Hover over Calculate , click the down arrow on
the screwdriver that appears, and select Create definition of 'Calculate' in
Calculator.cpp .

This code is added to Calculator.cpp :


Currently, it just returns 0.0. Let's change that.

4. Switch to the Calculator.cpp file in the editor window. Replace the contents of
Calculator::Calculate(double x, char oper, double y) with:

C++

double Calculator::Calculate(double x, char oper, double y)


{
switch(oper)
{
case '+':
return x + y;
case '-':
return x - y;
case '*':
return x * y;
case '/':
return x / y;
default:
return 0.0;
}
}

Understanding the code

The function Calculate consumes a number, an operator, and a second


number, then performs the requested operation on the numbers.
The switch statement checks which operator was provided, and only
executes the case corresponding to that operation. The default: case is a
fallback in case the user types an operator that isn't accepted, so the
program doesn't break. In general, it's best to handle invalid user input in
a more elegant way, but this is beyond the scope of this tutorial.
The double keyword denotes a type of number that supports decimals.
This way, the calculator can handle both decimal math and integer math.
The Calculate function is required to always return such a number due
to the double at the very start of the code (this denotes the function's
return type), which is why we return 0.0 even in the default case.
The .h file declares the function prototype, which tells the compiler
upfront what parameters it requires, and what return type to expect from
it. The .cpp file has all the implementation details of the function.

If you build and run the code again at this point, it will immediately exit after asking
which operation to perform. So, modify the main function to do multiple calculations.

Call the Calculator class member functions


1. Update the main function in CalculatorTutorial.cpp as follows:

C++

// CalculatorTutorial.cpp : This file contains the 'main' function.


Program execution begins and ends there.
//

#include <iostream>
#include "Calculator.h"

using namespace std;

int main()
{
double x = 0.0;
double y = 0.0;
double result = 0.0;
char oper = '+';

cout << "Calculator Console Application" << endl << endl;


cout << "Please enter the operation to perform. Format: a+b | a-b |
a*b | a/b"
<< endl;

Calculator c;
while (true)
{
cin >> x >> oper >> y;
result = c.Calculate(x, oper, y);
cout << "Result " << "of " << x << oper << y << " is: " <<
result << endl;
}

return 0;
}

Understanding the code

Since C++ programs always start at the main() function, we need to call
our other code from there, so a #include statement is needed.
Some initial variables x , y , oper , and result are declared to store the
first number, second number, operator, and final result, respectively. It's
always good practice to give them some initial values to avoid undefined
behavior, which is what is done here.
The Calculator c; line declares an object named 'c' as an instance of the
Calculator class. The class itself is just a blueprint for how calculators
work; the object is the specific calculator that does the math.
The while (true) statement is a loop. The code inside the loop continues
to execute over and over again as long as the condition inside the ()
holds true. Since the condition is simply listed as true , it's always true, so
the loop runs forever. To close the program, the user must manually close
the console window. Otherwise, the program always waits for new input.
The cin keyword is used to accept input from the user. This input stream
is smart enough to process a line of text entered in the console window
and place it inside each of the variables listed, in order, assuming the user
input matches the required specification. You can modify this line to
accept different types of input such as more than two numbers--though
the Calculate() function would also need to be updated to handle this.
The c.Calculate(x, oper, y); expression calls the Calculate function
defined earlier, and supplies the entered input values. The function then
returns a number that gets stored in result .
Finally, result is printed to the console, so the user sees the result of the
calculation.

Build and test the code again


Now test the program again to make sure everything works properly.

1. Press Ctrl+F5 to rebuild and start the app.

2. Enter 5+5 , and press Enter. Verify that the result is 10.
Debug the app
Since the user is free to type anything into the console window, let's make sure the
calculator handles unexpected input. Instead of running the program, let's debug it so
we can inspect what it's doing step-by-step.

Run the app in the debugger


1. In CalcuatorTutorial.cpp , set a breakpoint on the line: result = c.Calculate(x,
oper, y); . To set the breakpoint, click next to the line in the gray vertical bar along

the left edge of the editor window. A red dot appears.

Now when we debug the program, execution pauses at that line. We already have
a rough idea that the program works for simple cases. Since we don't want to
pause execution every time we call Calculate() , let's make the breakpoint
conditional.

2. Right-click the red dot that represents the breakpoint, and select Conditions. In
the edit box for the condition, enter (y == 0) && (oper == '/') . Select the Close
button to save the breakpoint condition.

Now, execution will pause at the breakpoint when the app tries to divide by 0.

3. To debug the program, press F5, or select the Local Windows Debugger toolbar
button that has the green arrow icon. In your console app, if you enter something
like "5 - 0", the program behaves normally and keeps running. However, if you
type "10 / 0", it pauses at the breakpoint. You can put any number of spaces
between the operator and numbers: cin is smart enough to parse the input
appropriately.

Useful windows in the debugger


When you debug your code, you may notice that some new windows appear. These
windows can assist your debugging experience. Take a look at the Autos window. The
Autos window shows you the current values of variables used at least three lines before
and up to the current line.

To see all of the variables from that function, switch to the Locals window. You can
modify the values of these variables while debugging to see what effect they would
have on the program. In this case, we leave them alone.

You can also hover over variables in the code to see their current values at the point
where execution is currently paused. Make sure the editor window is in focus by clicking
on it first.

Continue debugging
1. The yellow arrow on the left shows the current point of execution. The current line
calls Calculate , so press F11 to Step Into the function. Now you're executing code
in the body of the Calculate function. Be careful with Step Into because it steps
into any functions on the line you're on, including standard library functions. It's
fine to step into the standard library, but you may be more interested in focusing
on your code instead of library code.

2. Now that the point of execution is at the start of the Calculate function, press F10
to move to the next line in the program's execution. F10 is also known as Step
Over. You can use Step Over to move from line to line, without delving into the
details of what is occurring in each part of the line. In general, you should use Step
Over instead of Step Into unless you want to dive more deeply into code that is
being called from elsewhere (as you did to reach the body of Calculate ).

3. Continue using F10 to Step Over each line until you get back to the main()
function in the other file, and stop on the cout line.

The program is doing what's expected: it takes the first number, and divides it by
the second. On the cout line, hover over the result variable or take a look at
result in the Autos window. Its value inf , which doesn't look right, so let's fix it.

The cout line just outputs whatever value is stored in result , so when you step
one more line forward using F10, the console window displays:

This result is because division by zero is undefined, so the program doesn't have a
numerical answer for the requested operation.

Fix the "divide by zero" error


Let's handle division by zero more gracefully so that it's easier for the user to
understand the problem.
1. Make the following changes in CalculatorTutorial.cpp . (You can leave the
program running as you edit, thanks to a debugger feature called Edit and
Continue). Add an if statement following cin >> x >> oper >> y; to check for
division by zero and output a message to the user if it happens. Otherwise, the
result is printed.

C++

// CalculatorTutorial.cpp : This file contains the 'main' function.


Program execution begins and ends there.
//

#include <iostream>
#include "Calculator.h"

using namespace std;

int main()
{
double x = 0.0;
double y = 0.0;
double result = 0.0;
char oper = '+';

cout << "Calculator Console Application" << endl << endl;


cout << "Please enter the operation to perform. Format: a+b | a-b |
a*b | a/b" << endl;

Calculator c;
while (true)
{
cin >> x >> oper >> y;
if (oper == '/' && y == 0)
{
cout << "Math error: Attempted to divide by zero!" << endl;
continue;
}
else
{
result = c.Calculate(x, oper, y);
}
cout << "Result " << "of " << x << oper << y << " is: " <<
result << endl;
}

return 0;
}

2. Press F5 once. Program execution continues all the way until it has to pause to ask
for user input. Enter 10 / 0 again. Now, a more helpful message is printed. The
user is asked for more input, and the program continues executing normally.

7 Note

When you edit code while in debugging mode, there is a risk of code
becoming stale. This happens when the debugger is still running your old
code, and has not yet updated it with your changes. The debugger displays a
dialog to inform you when this happens. Sometimes, you may need to press
F5 to refresh the code being executed. In particular, if you make a change
inside a function while the point of execution is inside that function, you need
to step out of the function, then back into it again to get the updated code. If
that doesn't work and you see an error message, you can stop debugging by
clicking on the red square in the toolbar under the menus at the top of the
IDE, then start debugging again by entering F5 or by choosing the green
"play" arrow beside the stop button on the toolbar.

Another reason edit and continue may fail is if you see a message that says
"The Require source files to exactly match the original version setting under
Debug->Options->General needs to be enabled..." To fix this, from the main
menu select Tools > Options > Debugging > General and ensure that
Require source files to exactly match the original version is checked.

Understanding the Run and Debug shortcuts

F5 (or Debug > Start Debugging) starts a debugging session if one isn't
already active, and runs the program until a breakpoint is hit or the
program needs user input. If no user input is needed and no breakpoint
is available to hit, the program terminates and the console window closes
itself when the program finishes running. If you have something like a
"Hello World" program to run, use Ctrl+F5 or set a breakpoint before you
press F5 to keep the window open.
Ctrl+F5 (or Debug > Start Without Debugging) runs the application
without going into debug mode. This is slightly faster than debugging,
and the console window stays open after the program finishes executing.
F10 (known as Step Over) lets you iterate through code, line-by-line, and
visualize how the code is run and what variable values are at each step of
execution.
F11 (known as Step Into) works similarly to Step Over, except it steps into
any functions called on the line of execution. For example, if the line
being executed calls a function, pressing F11 moves the pointer into the
body of the function, so you can follow the function's code being run
before coming back to the line you started at. Pressing F10 steps over the
function call and just moves to the next line; the function call still
happens, but the program doesn't pause to show you what it's doing.

Close the app


If it's still running, close the console window for the calculator app.

Add Git source control


Now that you've created an app, you might want to add it to a Git repository. We've got
you covered. Visual Studio makes that process easy with Git tools you can use directly
from the IDE.

 Tip

Git is the most widely used modern version control system, so whether you're a
professional developer or you're learning how to code, Git can be very useful. If
you're new to Git, the https://git-scm.com/ website is a good place to start.
There, you can find cheat sheets, a popular online book, and Git Basics videos.

To associate your code with Git, you start by creating a new Git repository where your
code is located. Here's how:

1. In the status bar at the bottom-right corner of Visual Studio, select Add to Source
Control, and then select Git.
2. In the Create a Git repository dialog box, sign in to GitHub.

The repository name auto-populates based on your folder location. By default,


your new repository is private, which means you're the only one who can access it.

 Tip

Whether your repository is public or private, it's best to have a remote backup
of your code stored securely on GitHub. Even if you aren't working with a
team, a remote repository makes your code available to you from any
computer.

3. Select Create and Push.

After you create your repository, status details appear in the status bar.
The first icon with the arrows shows how many outgoing/incoming commits are in
your current branch. You can use this icon to pull any incoming commits or push
any outgoing commits. You can also choose to view these commits first. To do so,
select the icon, and then select View Outgoing/Incoming.

The second icon with the pencil shows the number of uncommitted changes to
your code. You can select this icon to view those changes in the Git Changes
window.

To learn more about how to use Git with your app, see the Visual Studio version control
documentation.

The finished app


Congratulations! You completed the code for the calculator app, built and debugged it,
and added it to a repo, all in Visual Studio.

Next steps
Learn more about Visual Studio for C++

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Get started with C++/WinRT
Article • 02/13/2023

) Important

For info about setting up Visual Studio for C++/WinRT development—including


installing and using the C++/WinRT Visual Studio Extension (VSIX) and the NuGet
package (which together provide project template and build support)—see Visual
Studio support for C++/WinRT.

To get you up to speed with using C++/WinRT, this topic walks through a simple code
example based on a new Windows Console Application (C++/WinRT) project. This
topic also shows how to add C++/WinRT support to a Windows Desktop application
project.

7 Note

While we recommend that you develop with the latest versions of Visual Studio and
the Windows SDK, if you're using Visual Studio 2017 (version 15.8.0 or later), and
targeting the Windows SDK version 10.0.17134.0 (Windows 10, version 1803), then
a newly created C++/WinRT project may fail to compile with the error "error C3861:
'from_abi': identifier not found", and with other errors originating in base.h. The
solution is to either target a later (more conformant) version of the Windows SDK,
or set project property C/C++ > Language > Conformance mode: No (also, if
/permissive- appears in project property C/C++ > Language > Command Line
under Additional Options, then delete it).

A C++/WinRT quick-start
Create a new Windows Console Application (C++/WinRT) project.

Edit pch.h and main.cpp to look like this.

C++/WinRT

// pch.h
#pragma once
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.Web.Syndication.h>
#include <iostream>

C++/WinRT

// main.cpp
#include "pch.h"

using namespace winrt;


using namespace Windows::Foundation;
using namespace Windows::Web::Syndication;

int main()
{
winrt::init_apartment();

Uri rssFeedUri{ L"https://blogs.windows.com/feed" };


SyndicationClient syndicationClient;
syndicationClient.SetRequestHeader(L"User-Agent", L"Mozilla/5.0
(compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)");
SyndicationFeed syndicationFeed =
syndicationClient.RetrieveFeedAsync(rssFeedUri).get();
for (const SyndicationItem syndicationItem : syndicationFeed.Items())
{
winrt::hstring titleAsHstring = syndicationItem.Title().Text();

// A workaround to remove the trademark symbol from the title


string, because it causes issues in this case.
std::wstring titleAsStdWstring{ titleAsHstring.c_str() };
titleAsStdWstring.erase(remove(titleAsStdWstring.begin(),
titleAsStdWstring.end(), L'™'), titleAsStdWstring.end());
titleAsHstring = titleAsStdWstring;

std::wcout << titleAsHstring.c_str() << std::endl;


}
}

Let's take the short code example above piece by piece, and explain what's going on in
each part.

C++/WinRT

#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.Web.Syndication.h>

With the default project settings, the included headers come from the Windows SDK,
inside the folder
%WindowsSdkDir%Include<WindowsTargetPlatformVersion>\cppwinrt\winrt . Visual Studio

includes that path in its IncludePath macro. But there's no strict dependency on the
Windows SDK, because your project (via the cppwinrt.exe tool) generates those same
headers into your project's $(GeneratedFilesDir) folder. They'll be loaded from that
folder if they can't be found elsewhere, or if you change your project settings.

The headers contain Windows APIs projected into C++/WinRT. In other words, for each
Windows type, C++/WinRT defines a C++-friendly equivalent (called the projected type).
A projected type has the same fully-qualified name as the Windows type, but it's placed
in the C++ winrt namespace. Putting these includes in your precompiled header
reduces incremental build times.

) Important

Whenever you want to use a type from a Windows namespaces, you must #include
the corresponding C++/WinRT Windows namespace header file, as shown above.
The corresponding header is the one with the same name as the type's namespace.
For example, to use the C++/WinRT projection for the
Windows::Foundation::Collections::PropertySet runtime class, include the
winrt/Windows.Foundation.Collections.h header.

It is common for a C++/WinRT projection header to automatically include related


namespace header files. For example, winrt/Windows.Foundation.Collections.h
includes winrt/Windows.Foundation.h . But you shouldn't rely on this behavior, since
it's an implementation detail that changes over time. You must explicitly include
any headers that you need.

C++/WinRT

using namespace winrt;


using namespace Windows::Foundation;
using namespace Windows::Web::Syndication;

The using namespace directives are optional, but convenient. The pattern shown above
for such directives (allowing unqualified name lookup for anything in the winrt
namespace) is suitable for when you're beginning a new project and C++/WinRT is the
only language projection you're using inside of that project. If, on the other hand, you're
mixing C++/WinRT code with C++/CX and/or SDK application binary interface (ABI)
code (you're either porting from, or interoperating with, one or both of those models),
then see the topics Interop between C++/WinRT and C++/CX, Move to C++/WinRT
from C++/CX, and Interop between C++/WinRT and the ABI.

C++/WinRT
winrt::init_apartment();

The call to winrt::init_apartment initializes the thread in the Windows Runtime; by


default, in a multithreaded apartment. The call also initializes COM.

C++/WinRT

Uri rssFeedUri{ L"https://blogs.windows.com/feed" };


SyndicationClient syndicationClient;

Stack-allocate two objects: they represent the uri of the Windows blog, and a
syndication client. We construct the uri with a simple wide string literal (see String
handling in C++/WinRT for more ways you can work with strings).

C++/WinRT

SyndicationFeed syndicationFeed =
syndicationClient.RetrieveFeedAsync(rssFeedUri).get();

SyndicationClient::RetrieveFeedAsync is an example of an asynchronous Windows


Runtime function. The code example receives an asynchronous operation object from
RetrieveFeedAsync, and it calls get on that object to block the calling thread and wait
for the result (which is a syndication feed, in this case). For more about concurrency, and
for non-blocking techniques, see Concurrency and asynchronous operations with
C++/WinRT.

C++/WinRT

for (const SyndicationItem syndicationItem : syndicationFeed.Items()) { ...


}

SyndicationFeed.Items is a range, defined by the iterators returned from begin and end
functions (or their constant, reverse, and constant-reverse variants). Because of this, you
can enumerate Items with either a range-based for statement, or with the std::for_each
template function. Whenever you iterate over a Windows Runtime collection like this,
you'll need to #include <winrt/Windows.Foundation.Collections.h> .

C++/WinRT

winrt::hstring titleAsHstring = syndicationItem.Title().Text();

// Omitted: there's a little bit of extra work here to remove the trademark
symbol from the title text.
std::wcout << titleAsHstring.c_str() << std::endl;

Gets the feed's title text, as a winrt::hstring object (more details in String handling in
C++/WinRT). The hstring is then output, via the c_str function, which reflects the pattern
used with C++ Standard Library strings.

As you can see, C++/WinRT encourages modern, and class-like, C++ expressions such
as syndicationItem.Title().Text() . This is a different, and cleaner, programming style
from traditional COM programming. You don't need to directly initialize COM, nor work
with COM pointers.

Nor do you need to handle HRESULT return codes. C++/WinRT converts error HRESULTs
to exceptions such as winrt::hresult-error for a natural and modern programming style.
For more info about error-handling, and code examples, see Error handling with
C++/WinRT.

Modify a Windows Desktop application project


to add C++/WinRT support
Some desktop projects (for example, the WinUI 3 templates in Visual Studio) have
C++/WinRT support built in.

But this section shows you how you can add C++/WinRT support to any Windows
Desktop application project that you might have. If you don't have an existing Windows
Desktop application project, then you can follow along with these steps by first creating
one. For example, open Visual Studio and create a Visual C++ > Windows Desktop >
Windows Desktop Application project.

You can optionally install the C++/WinRT Visual Studio Extension (VSIX) and the
NuGet package. For details, see Visual Studio support for C++/WinRT.

Set project properties


Go to project property General > Windows SDK Version, and select All Configurations
and All Platforms. Ensure that Windows SDK Version is set to 10.0.17134.0 (Windows
10, version 1803) or greater.

Confirm that you're not affected by Why won't my new project compile?.

Because C++/WinRT uses features from the C++17 standard, set project property
C/C++ > Language > C++ Language Standard to ISO C++17 Standard (/std:c++17).
The precompiled header
The default project template creates a precompiled header for you, named either
framework.h , or stdafx.h . Rename that to pch.h . If you have a stdafx.cpp file, then

rename that to pch.cpp . Set project property C/C++ > Precompiled Headers >
Precompiled Header to Create (/Yc), and Precompiled Header File to pch.h.

Find and replace all #include "framework.h" (or #include "stdafx.h" ) with #include
"pch.h" .

In pch.h , include winrt/base.h .

C++/WinRT

// pch.h
...
#include <winrt/base.h>

Linking
The C++/WinRT language projection depends on certain Windows Runtime free (non-
member) functions, and entry points, that require linking to the WindowsApp.lib
umbrella library. This section describes three ways of satisfying the linker.

The first option is to add to your Visual Studio project all of the C++/WinRT MSBuild
properties and targets. To do this, install the Microsoft.Windows.CppWinRT NuGet
package into your project. Open the project in Visual Studio, click Project > Manage
NuGet Packages... > Browse, type or paste Microsoft.Windows.CppWinRT in the search
box, select the item in search results, and then click Install to install the package for that
project.

You can also use project link settings to explicitly link WindowsApp.lib . Or, you can do it
in source code (in pch.h , for example) like this.

C++/WinRT

#pragma comment(lib, "windowsapp")

You can now compile and link, and add C++/WinRT code to your project (for example,
code similar to that shown in the A C++/WinRT quick-start section, above).

The three main scenarios for C++/WinRT


As you use and become familiar with C++/WinRT, and work through the rest of the
documentation here, you'll likely notice that there are three main scenarios, as described
in the following sections.

Consuming Windows APIs and types


In other words, using, or calling APIs. For example, making API calls to communicate
using Bluetooth; to stream and present video; to integrate with the Windows shell; and
so on. C++/WinRT fully and uncompromisingly supports this category of scenario. For
more info, see Consume APIs with C++/WinRT.

Authoring Windows APIs and types


In other words, producing APIs and types. For example, producing the kinds of APIs
described in the section above; or the graphics APIs; the storage and file system APIs;
the networking APIs, and so on. For more info, see Author APIs with C++/WinRT.

Authoring APIs with C++/WinRT is a little more involved than consuming them, because
you must use IDL to define the shape of the API before you can implement it. There's a
walkthrough of doing that in XAML controls; bind to a C++/WinRT property.

XAML applications
This scenario is about building applications and controls on the XAML UI framework.
Working in a XAML application amounts to a combination of consuming and authoring.
But since XAML is the dominant UI framework on Windows today, and its influence over
the Windows Runtime is proportionate to that, it deserves its own category of scenario.

Be aware that XAML works best with programming languages that offer reflection. In
C++/WinRT, you sometimes have to do a little extra work in order to interoperate with
the XAML framework. All of those cases are covered in the documentation. Good places
to start are XAML controls; bind to a C++/WinRT property and XAML custom
(templated) controls with C++/WinRT.

Sample apps written in C++/WinRT


See Where can I find C++/WinRT sample apps?.

Important APIs
SyndicationClient::RetrieveFeedAsync method
SyndicationFeed.Items property
winrt::hstring struct
winrt::hresult-error struct

Related topics
C++/CX
Error handling with C++/WinRT
Interop between C++/WinRT and C++/CX
Interop between C++/WinRT and the ABI
Move to C++/WinRT from C++/CX
String handling in C++/WinRT

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Get Started with Win32 and C++
Article • 01/27/2022

The aim of this Get Started series is to teach you how to write a desktop program in
C++ using Win32 and COM APIs.

In the first module, you'll learn step-by-step how to create and show a window. Later
modules will introduce the Component Object Model (COM), graphics and text, and
user input.

For this series, it is assumed that you have a good working knowledge of C++
programming. No previous experience with Windows programming is assumed. If you
are new to C++, learning material is available in the C++ language documentation .

In this section
Topic Description

Intro to Win32 This section describes some of the basic terminology and coding
programming in C++ conventions used in Windows programming.

Module 1. Your First In this module, you will create a simple Windows program that
Windows Program shows a blank window.

Module 2. Using COM in This module introduces the Component Object Model (COM),
Your Windows Program which underlies many of the modern Windows APIs.

Module 3. Windows This module introduces the Windows graphics architecture, with a
Graphics focus on Direct2D.

Module 4. User Input This module describes mouse and keyboard input.

Sample Code Contains links to download the sample code for this series.

Feedback
Was this page helpful? ツ Yes ト No

Get help at Microsoft Q&A


Create a simple Universal Windows
Platform (UWP) game with DirectX
Article • 10/20/2022

In this set of tutorials, you'll learn how to use DirectX and C++/WinRT to create the basic
Universal Windows Platform (UWP) sample game named Simple3DGameDX. The
gameplay takes place in a simple first-person 3D shooting gallery.

7 Note

The link from which you can download the Simple3DGameDX sample game itself is
Direct3D sample game. The C++/WinRT source code is in the folder named
cppwinrt . For info about other UWP sample apps, see Sample applications for

Windows development.

These tutorials cover all of the major parts of a game, including the processes for
loading assets such as arts and meshes, creating a main game loop, implementing a
simple rendering pipeline, and adding sound and controls.

You'll also see UWP game development techniques and considerations. We'll focus on
key UWP DirectX game development concepts, and call out Windows-Runtime-specific
considerations around those concepts.

Objective
To learn about the basic concepts and components of a UWP DirectX game, and to
become more comfortable designing UWP games with DirectX.

What you need to know


For this tutorial, you need to be familiar with these subjects.

C++/WinRT. C++/WinRT is a standard modern C++17 language projection for


Windows APIs, implemented as a header-file-based library, and designed to
provide you with first-class access to the modern Windows APIs.
Basic linear algebra and Newtonian physics concepts.
Basic graphics programming terminology.
Basic Windows programming concepts.
Basic familiarity with the Direct2D and Direct3D 11 APIs.
Direct3D UWP shooting gallery sample
The Simple3DGameDX sample game implements a simple first-person 3D shooting
gallery, where the player fires balls at moving targets. Hitting each target awards a set
number of points, and the player can progress through 6 levels of increasing challenge.
At the end of the levels, the points are tallied, and the player is awarded a final score.

The sample demonstrates these game concepts.

Interoperation between DirectX 11.1 and the Windows Runtime


A first-person 3D perspective and camera
Stereoscopic 3D effects
Collision-detection between objects in 3D
Handling player input for mouse, touch, and Xbox controller controls
Audio mixing and playback
A basic game state-machine

Topic Description

Set up the The first step in developing your game is to set up a project in Microsoft Visual
game project Studio. After you've configured a project specifically for game development, you
could later re-use it as a kind of template.

Define the The first step in coding a Universal Windows Platform (UWP) game is building
game's UWP the framework that lets the app object interact with Windows.
app framework

Game flow Define the high-level state machine to enable player and system interaction.
management Learn how UI interacts with the overall game's state machine and how to create
event handlers for UWP games.
Topic Description

Define the Now, we look at the details of the sample game's main object and how the rules
main game it implements translate into interactions with the game world.
object

Rendering Learn how to develop the rendering pipeline to display graphics. Intro to
framework I: rendering.
Intro to
rendering

Rendering Learn how to assemble the rendering pipeline to display graphics. Game
framework II: rendering, set up and prepare data.
Game
rendering

Add a user Learn how to add a 2D user interface overlay to a DirectX UWP game.
interface

Add controls Now, we take a look at how the sample game implements move-look controls
in a 3-D game, and how to develop basic touch, mouse, and game controller
controls.

Add sound Develop a simple sound engine using XAudio2 APIs to playback game music
and sound effects.

Extend the Learn how to implement a XAML overlay for a UWP DirectX game.
sample game
C/C++ projects and build systems in
Visual Studio
Article • 12/09/2021

You can use Visual Studio to edit, compile, and build any C++ code base with full
IntelliSense support without having to convert that code into a Visual Studio project or
compile with the MSVC toolset. For example, you can edit a cross-platform CMake
project in Visual Studio on a Windows machine, then compile it for Linux using g++ on
a remote Linux machine.

C++ compilation
To build a C++ program means to compile source code from one or more files and then
link those files into an executable file (.exe), a dynamic-load library (.dll) or a static library
(.lib).

Basic C++ compilation involves three main steps:

The C++ preprocessor transforms all the #directives and macro definitions in each
source file. This creates a translation unit.
The C++ compiler compiles each translation unit into object files (.obj), applying
whatever compiler options have been set.
The linker merges the object files into a single executable, applying the linker
options that have been set.

The MSVC toolset


The Microsoft C++ compiler, linker, standard libraries, and related utilities make up the
MSVC compiler toolset (also called a toolchain or "build tools"). These are included in
Visual Studio. You can also download and use the command-line toolset as a free
standalone package. For more information, see Build Tools for Visual Studio on the
Visual Studio Downloads page.

You can build simple programs by invoking the MSVC compiler (cl.exe) directly from the
command line. The following command accepts a single source code file, and invokes
cl.exe to build an executable called hello.exe:

Windows Command Prompt

cl /EHsc hello.cpp
Here the compiler (cl.exe) automatically invokes the C++ preprocessor and the linker to
produce the final output file. For more information, see Building on the command line.

Build systems and projects


Most real-world programs use some kind of build system to manage complexities of
compiling multiple source files for multiple configurations (debug vs. release), multiple
platforms (x86, x64, ARM, and so on), custom build steps, and even multiple executables
that must be compiled in a certain order. You make settings in a build configuration
file(s), and the build system accepts that file as input before it invokes the compiler. The
set of source code files and build configuration files needed to build an executable file is
called a project.

The following list shows various options for Visual Studio Projects - C++:

create a Visual Studio project by using the Visual Studio IDE and configure it by
using property pages. Visual Studio projects produce programs that run on
Windows. For an overview, see Compiling and Building in the Visual Studio
documentation.

open a folder that contains a CMakeLists.txt file. CMake support is integrated into
Visual Studio. You can use the IDE to edit, test, and debug without modifying the
CMake files in any way. This enables you to work in the same CMake project as
others who might be using different editors. CMake is the recommended approach
for cross-platform development. For more information, see CMake projects.

open a loose folder of source files with no project file. Visual Studio will use
heuristics to build the files. This is an easy way to compile and run small console
applications. For more information, see Open Folder projects.

open a folder that contains a makefile, or any other build system configuration file.
You can configure Visual Studio to invoke any arbitrary build commands by adding
JSON files to the folder. For more information, see Open Folder projects.

Open a Windows makefile in Visual Studio. For more information, see NMAKE
Reference.

MSBuild from the command line


You can invoke MSBuild from the command line by passing it a .vcxproj file along with
command-line options. This approach requires a good understanding of MSBuild, and is
recommended only when necessary. For more information, see MSBuild.

In This Section
Visual Studio projects
How to create, configure, and build C++ projects in Visual Studio using its native build
system (MSBuild).

CMake projects
How to code, build, and deploy CMake projects in Visual Studio.

Open Folder projects


How to use Visual Studio to code, build, and deploy C++ projects based on any arbitrary
build system, or no build system at all.

Release builds
How to create and troubleshoot optimized release builds for deployment to end users.

Use the MSVC toolset from the command line


Discusses how to use the C/C++ compiler and build tools directly from the command
line rather than using the Visual Studio IDE.

Building DLLs in Visual Studio


How to create, debug, and deploy C/C++ DLLs (shared libraries) in Visual Studio.

Walkthrough: Creating and Using a Static Library


How to create a .lib binary file.

Building C/C++ Isolated Applications and Side-by-side Assemblies


Describes the deployment model for Windows Desktop applications, based on the idea
of isolated applications and side-by-side assemblies.

Configure C++ projects for 64-bit, x64 targets


How to target 64-bit x64 hardware with the MSVC build tools.

Configure C++ projects for ARM processors


How to use the MSVC build tools to target ARM hardware.

Optimizing Your Code


How to optimize your code in various ways including program guided optimizations.

Configuring Programs for Windows XP


How to target Windows XP with the MSVC build tools.
C/C++ Building Reference
Provides links to reference articles about program building in C++, compiler and linker
options, and various build tools.
Read and understand C++ code in
Visual Studio
Article • 09/27/2022

The C++ code editor and Visual Studio IDE provide many coding aids. Some are unique
to C++, and some are essentially the same for all Visual Studio languages. For more
information about the shared features, see Writing Code in the Code and Text Editor.

Colorization
Visual Studio colorizes syntax elements to differentiate between types of symbols such
as language keywords, type names, variable names, function parameters, string literals,
and so on.

Unused code (such as code under an #if 0) is more faded in color.

You can customize the colors by typing "Fonts" in Quick Launch, and then choosing
Fonts and Colors. In the Fonts and Colors dialog, scroll down to the C/C++ options and
then choose a custom font and/or color.
Outlining
Right-click anywhere in a source code file and choose Outlining to collapse or expand
code blocks and/or custom regions to make it easier to browse only the code you're
interested in. For more information, see Outlining.

When you place your cursor in front of a curly brace, '{' or '}', the editor highlights its
matching counterpart.

Other outlining options are located under Edit > Outlining in the main menu.

Line numbers
You can add line numbers to your project by going to Tools > Options > Text Editor >
All Languages > General or by searching for "line num" with Quick Launch (Ctrl + Q).
Line numbers can be set for all languages or for specific languages only, including C++.

Scroll and zoom


You can zoom in or out in the editor by pressing the Ctrl key and scrolling with your
mouse wheel. You can also zoom by using the zoom setting in the bottom left corner.
Scrollbar Map Mode enables you to quickly scroll and browse through a code file
without leaving your current location. You can click anywhere on the code map to go
directly to that location.

To turn on Map Mode, type "map" in the Quick Launch search box in the main toolbar
and choose Use scroll map mode. For more information, see How to: Track your code
by customizing the scrollbar.

When Map Mode is off, the scroll bar still highlights the changes you have made in the
file. Green indicates saved changes and yellow indicates unsaved changes.

Quick Info and Parameter Info


Hover over any variable, function, or other symbol to get information about it, including
the declaration, and any comments that are located just preceding it.
The Quick Info tooltip has a Search Online link. Go to Tools > Options > Text Editor >
C++ > View to specify the search provider.

If there's an error in your code, you can hover over it, and Quick Info will display the
error message. You can also find the error message in the Error List window.

When you call a function, Parameter Info shows the types of parameters and the order
in which they're expected.

Peek Definition
Hover over a variable or function declaration, right-click, then choose Peek Definition to
see an inline view of its definition without navigating away from your current location.
For more information, see Peek Definition (Alt+F12).
F1 Help
Place the cursor on or just after any type, keyword or function and press F1 to go
directly to the relevant reference topic on Microsoft Learn. F1 also works on items in the
error list and in many dialog boxes.

Class View
Class View displays a searchable set of trees of all code symbols and their scope and
parent/child hierarchies, organized on a per-project basis. You can configure what Class
View displays from Class View Settings (click the gear box icon at the top of the
window).
Generate graph of include files
Right click on a code file in your project and choose Generate graph of include files to
see a graph of which files are included by other files.

View Call Hierarchy


Right click on any function call and view a recursive list of all the functions that it calls,
and all the functions that call it. Each function in the list can be expanded in the same
way. For more information, see Call Hierarchy.
See Also
Edit and refactor code (C++)
Navigate your C++ code base in Visual Studio
Collaborate with Live Share for C++
Windows C++ desktop application
types
Article • 03/27/2024

A desktop application in C++ is a native application that can access the full set of
Windows APIs, and either runs in a window or in the system console. Desktop
applications in C++ can run on Windows XP through Windows 11 (although Windows
XP is no longer officially supported and there are many new Windows APIs since then).

Any desktop application in C++ can use C Runtime (CRT) and Standard Library classes
and functions, COM objects, and the public Windows functions, which collectively are
known as the Windows API. For an introduction to Windows desktop applications in
C++, see Get Started with Win32 and C++.

There are several broad categories of Windows applications that you can create with
C++, described below. Each has its own programming model and set of Windows-
specific libraries. The C++ standard library and third-party C++ libraries can be used in
any of them.

For documentation on the Windows platform itself, see Windows documentation.

Native desktop client applications


A native desktop client application, or Win32 application, is a Windows desktop
application written in C or C++ that uses native Windows C APIs or Component Object
Model (COM) APIs CRT and Standard Library APIs, and 3rd party libraries. A Win32
application that runs in a window requires the developer to handle Windows messages
inside a Windows procedure function. Despite the name, a Win32 application can be
compiled as a 32-bit (x86) or 64-bit (x64) binary. In the Visual Studio IDE, the terms x86
and Win32 are synonymous.

To get started with traditional Windows C++ programming, see Get Started with
Win32 and C++.
For an example of a traditional C++ desktop application that uses sophisticated
graphics, see Hilo: Developing C++ Applications for Windows.

Command line (console) applications


C++ console applications run from the command line in a console window and can
display text output only.
For more information, see Create a console calculator in C++.

UWP applications
The Universal Windows Platform (UWP) is the modern Windows API. UWP apps run on
Windows 11, Windows 10, XBox, Windows Phone, Surface Hub, and other devices. UWP
apps use XAML for the user-interface, and are fully touch-enabled. A desktop
application is distinct from a Universal Windows Platform (UWP) app.

For more information about desktop vs. UWP applications, see Choose your
technology.
For more information about UWP, see What's a Universal Windows Platform (UWP)
app and Guide to Windows Universal Apps.

The original C++ support for UWP consisted of C++/CX, a dialect of C++ with syntax
extensions, or the Windows Runtime Library (WRL), which is based on standard C++ and
COM. Both C++/CX and WRL are still supported, but not recommended for new
development.

For new projects, we recommend C++/WinRT, which is entirely based on standard C++
and provides faster performance.

A C++/CLI application or component uses extensions to C++ syntax (as allowed by the
C++ Standard) to enable interaction between .NET and native C++code. A C++/CLI
application can have parts that run natively and parts that run on the .NET Framework
with access to the .NET Base Class Library. C++/CLI is the preferred option when you
have native C++ code that needs to work with code written in C# or Visual Basic. It's
intended for use in .NET DLLs rather than in user interface code.

For more information, see .NET Programming with C++/CLI (Visual C++).

Desktop Bridge
In Windows 10 and later, you can package your existing desktop application or COM
object as a UWP app. It can use UWP features such as touch, or call APIs from the
modern Windows API set. You can also add a UWP app to a desktop solution in Visual
Studio, package them together in a single package, and use Windows APIs to
communicate between them.

Visual Studio 2017 version 15.4 and later lets you create a Windows Application Package
Project to greatly simplify the work of packaging your existing desktop application. A
few restrictions apply to the registry calls or APIs your desktop application can use.
However, in many cases you can create alternate code paths to achieve similar
functionality while running in an app package.

For more information, see Desktop Bridge.

C++ or .NET?
In general, .NET programming in C# is less complex, less error-prone, and has a more
modern object-oriented API than Win32 or MFC. In most cases, its performance is more
than adequate.

.NET features the Windows Presentation Foundation (WPF) for rich graphics, and you
can consume both Win32 and the modern Windows Runtime API. As a general rule, we
recommend using C++ for desktop applications when you require:

precise control over memory usage


the utmost economy in power consumption
usage of the GPU for general computing
access to DirectX
heavy usage of standard C++ libraries

It's also possible to combine the power and efficiency of C++ with .NET programming.
You can create a user interface in C# and use C++/CLI to enable the application to
consume native C++ libraries.

For more information, see .NET Programming with C++/CLI.

Games
DirectX games can run on the PC or Xbox.

For more information, see DirectX Graphics and Gaming.

SQL Server database clients


To access SQL Server databases from native code, use ODBC or OLE DB.

For more information, see SQL Server Native Client.

Windows device drivers


Drivers are low-level components that make data from hardware devices accessible to
applications and other operating system components.

For more information, see Windows Driver Kit (WDK).

Windows services
A Windows service is a program that can run in the background with little or no user
interaction. These programs are called daemons on UNIX systems.

For more information, see Services.

COM
The Component Object Model (COM) is a specification that enables programs written in
different languages to interoperate with one another.

Many Windows components are implemented as COM objects and follow standard
COM rules for object creation, interface discovery, and object destruction. Using COM
objects from C++ desktop applications is relatively straightforward, but writing your
own COM object is more advanced.

The Active Template Library (ATL) provides macros and helper functions that simplify
COM development. For more information, see ATL COM desktop components.

MFC
An MFC application is a Windows desktop application that uses the Microsoft
Foundation Classes to create the user interface. An MFC application can also use COM
components and CRT and Standard Library APIs.

MFC provides a thin C++ object-oriented wrapper over the window message loop and
Windows APIs. MFC is the default choice for applications—especially enterprise-type
applications—that have many user interface controls or custom user controls.

MFC provides convenient helper classes for window management, serialization, text
manipulation, printing, and modern user interface elements such as the ribbon. To be
effective with MFC, you should be familiar with Win32.

SDKs, libraries, and header files


Visual Studio includes the C Runtime Library (CRT), the C++ Standard Library, and other
Microsoft-specific libraries. Most of the folders that contain header files for these
libraries are located in the Visual Studio installation directory under the \VC\ folder (for
example, C:\Program Files\Microsoft Visual
Studio\2022\Enterprise\VC\Tools\MSVC\14.39.33519\include\ ). The Windows and CRT

header files are found in the Windows SDK installation folder (for example, C:\Program
Files (x86)\Windows Kits\10\Include\10.0.22621.0\ucrt\ )

The vcpkg package manager lets you conveniently install hundreds of third-party open-
source libraries for Windows. For more information, see vcpkg.

The Microsoft libraries include:

Microsoft Foundation Classes (MFC): An object-oriented framework for creating


traditional Windows programs—especially enterprise applications—that have rich
user interfaces that feature buttons, list boxes, tree views, and other controls. For
more information, see MFC Desktop Applications.

Active Template Library (ATL): A powerful helper library for creating COM
components. For more information, see ATL COM Desktop Components.

C++ AMP (C++ Accelerated Massive Parallelism): A library that enables high-
performance general computational work on the GPU. For more information, see
C++ AMP (C++ Accelerated Massive Parallelism).

Concurrency Runtime: A library that simplifies the work of parallel and


asynchronous programming for multicore and many-core devices. For more
information, see Concurrency Runtime.

Many Windows programming scenarios also require the Windows SDK, which includes
the header files that enable access to the Windows operating system components. By
default, Visual Studio installs the Windows SDK as a component of the C++ Desktop
workload, which enables development of Universal Windows apps. To develop UWP
apps, you need a Windows 10 or later version of the Windows SDK.

For more information, and a download link, see Windows SDK .


For more information about the Windows SDKs for earlier versions of Windows,
see the Windows SDK archive.

The default location for all versions of the Windows SDK that you install is: Program
Files (x86)\Windows Kits .

Development Tools
Visual Studio includes a powerful debugger for native code, static analysis tools,
graphics debugging tools, a full-featured code editor, support for unit tests, and many
other tools and utilities.

For more information, see Get started developing with Visual Studio, and Overview
of C++ development in Visual Studio.

In this section
ノ Expand table

Link Description

Walkthrough: Creating Create a native Windows desktop application.


Windows desktop
applications (C++)

How to: Use the Windows Contains steps for setting up your project to build using the
SDK in a Windows desktop Windows SDK.
application

Walkthrough: Create a Create a Windows console application.


standard C++ program

Walkthrough: Create a Create a simple Windows console application. A Win32 (or Win64)
console calculator in C++ console application has no window of its own and no message loop.
It runs in the console window, and input and output are handled
through the command line.

Deploying native desktop Deploy native applications on Windows.


applications

Walkthrough: Creating How to create a .lib binary file.


and using a static library

Windows Desktop Wizard Use the wizard to create new Windows projects.

Active Template Library Use the ATL library to create COM components in C++.
(ATL)

ATL and MFC Shared Use classes such as CString that are shared in ATL and MFC.
classes

Microsoft Foundation Use MFC to create large or small Windows applications with dialogs
Classes (MFC) and controls

Data access OLE DB and ODBC

Text and strings Various string types on Windows.


Link Description

Working with resource How to add images, icons, string tables, and other resources to a
files desktop application.

Resources for creating a Links to content for creating games in C++.


game using DirectX (C++)

Related Articles
ノ Expand table

Title Description

Windows Contains information about the Windows API and COM. (Some Windows
development APIs and third-party DLLs are implemented as COM objects.)

Hilo: Developing Describes how to create a rich-client Windows desktop application that
C++ applications for uses Windows Animation and Direct2D to create a carousel-based user
Windows 7 interface. This tutorial hasn't been updated since Windows 7, but still
provides a thorough introduction to Win32 programming.

.NET development Create wrappers for native C++ libraries that enable it to communication
with C++/CLI with .NET applications and components.

Component Reference for syntax elements shared by C++/CX and C++/CLI.


extensions for .NET
and UWP

Universal Windows Write UWP applications using C++/CX or Windows Runtime Template
apps (C++) Library (WRL).

C++ attributes for Nonstandard attributes for Windows-only programming using .NET or
COM and .NET COM.

See also
C++ in Visual Studio

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Universal Windows Apps (C++)
Article • 10/06/2021

The Universal Windows Platform (UWP) is the modern programming interface for
Windows. With UWP you write an application or component once and deploy it on any
Windows 10 or later device. You can write a component in C++ and applications written
in any other UWP-compatible language can use it.

Most of the UWP documentation is in the Windows content tree at Universal Windows
Platform documentation. There you will find beginning tutorials as well as reference
documentation.

For new UWP apps and components, we recommend that you use C++/WinRT, a new
standard C++17 language projection for Windows Runtime APIs. C++/WinRT is
available in the Windows SDK from version 1803 (10.0.17134.0) onward. C++/WinRT is
implemented entirely in header files, and is designed to provide you with first-class
access to the modern Windows API. Unlike the C++/CX implementation, C++/WinRT
doesn't use non-standard syntax or Microsoft language extensions, and it takes full
advantage of the C++ compiler to create highly-optimized output. For more
information, see Introduction to C++/WinRT.

You can use the Desktop Bridge app converter to package your existing desktop
application for deployment through the Microsoft Store. For more information, see
Using Visual C++ Runtime in Centennial project and Desktop Bridge.

UWP apps that use C++/CX


C++/CX language reference
Describes the set of extensions that simplify C++ consumption of Windows Runtime
APIs and enable error handling that's based on exceptions.

Building apps and libraries (C++/CX)


Describes how to create DLLs and static libraries that can be accessed from a C++/CX
app or component.

Tutorial: Create a UWP "Hello, World" app in C++/CX


A walkthrough that introduces the basic concepts of UWP app development in C++/CX.

Creating Windows Runtime Components in C++/CX


Describes how to create DLLs that other UWP apps and components can consume.
UWP game programming
Describes how to use DirectX and C++/CX to create games.

UWP Apps that Use the Windows Runtime C++


Template Library (WRL)
The Windows Runtime C++ Template Library provides the low-level COM interfaces by
which ISO C++ code can access the Windows Runtime in an exception-free
environment. In most cases, we recommend that you use C++/WinRT or C++/CX
instead of the Windows Runtime C++ Template Library for UWP app development. For
information about the Windows Runtime C++ Template Library, see Windows Runtime
C++ Template Library (WRL).

See also
C++ in Visual Studio
Overview of Windows Programming in C++
Game Development with C++
Article • 10/06/2021

When you create a Universal Windows Platform (UWP) game, you have the opportunity
to reach millions of players worldwide across phone, PC, and Xbox One. With Xbox on
Windows, Xbox Live, cross-device multiplayer, an amazing gaming community, and
powerful new features like the Universal Windows Platform (UWP) and DirectX 12,
Windows games thrill players of all ages and genres. The new Universal Windows
Platform (UWP) delivers compatibility for your game across Windows devices with a
common API for phone, PC, and Xbox One, along with tools and options to tailor your
game to each device experience.

Game development is documented on the Windows Dev Center.


Linux development with C++ | Create
and debug applications for Linux
Use C++ in Visual Studio 2017 and later to create and debug applications for Linux.

Create Linux C++ apps in Visual Studio

b GET STARTED

Download, install, and set up the Linux workload

c HOW-TO GUIDE

Connect to your target Linux system

i REFERENCE

ConnectionManager reference

Build Linux projects in Visual Studio

f QUICKSTART

Create a new Linux project

Configure a Linux project

Deploy, run, and debug your Linux project

i REFERENCE

Linux Project Property Page Reference

Build Linux CMake projects in Visual Studio

f QUICKSTART

Create and configure a Linux CMake project


g TUTORIAL

Create C++ cross-platform projects in Visual Studio


Mobile Development with C++ |
Windows UWP, Android and iOS
Create native C++ apps for iOS, Android, and Windows devices with Visual Studio.

Learn how to build cross-platform mobile apps

b GET STARTED

Install cross-platform mobile development with C++

e OVERVIEW

Overview of cross-platform mobile development with C++

g TUTORIAL

Create an Android Native Activity App

d TRAINING

Cross-platform mobile development examples

Cross-platform reference

i REFERENCE

C++ cross-platform property page reference

Universal Windows Platform (UWP) documentation

iOS API documentation

Android API documentation


.NET programming with C++/CLI
Article • 10/29/2021

In Visual Studio 2022, the default target framework for .NET Core projects is 6.0. For
.NET Frameworks projects, the default is 4.7.2. The .NET Framework version selector is on
the Configure your new project page of the Create a new project dialog.

Install C++/CLI support in Visual Studio 2022


C++/CLI itself isn't installed by default when you install a Visual Studio C++ workload.
To install the component after Visual Studio is installed, open the Visual Studio Installer
by selecting the Windows Start menu and searching for visual studio installer. Choose
the Modify button next to your installed version of Visual Studio. Select the Individual
components tab. Scroll down to the Compilers, build tools, and runtimes section, and
select C++/CLI support for v143 build tools (Latest). Select Modify to download the
necessary files and update Visual Studio.

In this section
C++/CLI tasks

Native and .NET interoperability

Pure and verifiable code (C++/CLI)

Regular expressions (C++/CLI)

File handling and I/O (C++/CLI)

Graphics operations (C++/CLI)

Windows operations (C++/CLI)

Data access using ADO.NET (C++/CLI)

Interoperability with other .NET languages (C++/CLI)

Serialization (C++/CLI)

Managed types (C++/CLI)

Reflection (C++/CLI)
Strong Name assemblies (assembly signing) (C++/CLI)

Debug class (C++/CLI)

STL/CLR library reference

C++ support library

Exceptions in C++/CLI

Boxing (C++/CLI)

See also
Native and .NET interoperability
Cloud and Web Programming in Visual
C++
Article • 09/21/2021

In C++, you have several options for connecting to the web and the cloud.

Microsoft Azure SDKs and REST services


Microsoft Azure Storage Client Library for C++

The Azure Storage Client Library for C++ provides a comprehensive API for
working with Azure storage, including but not limited to the following abilities:
Create, read, delete, and list blob containers, tables, and queues.
Create, read, delete, list and copy blobs plus read and write blob ranges.
Insert, delete, replace, merge, and query entities in an Azure table.
Enqueue and dequeue messages in an Azure queue.
Lazily list containers, blobs, tables, and queues, and lazily query entities

The ANSI C99 Azure IoT Hub SDKs for Internet of Things enable IoT applications to
run on the device or on the backend.

OneDrive and SharePoint in Microsoft Graph

The OneDrive API provides a set of HTTP services to connect your application to
files and folders in Microsoft 365 and SharePoint Server 2016.

Windows and cross-platform networking APIs


C++ REST SDK (Code name "Casablanca")

Provides a modern, cross-platform, asynchronous API for interacting with REST


services.
Perform REST calls against any HTTP server, with built-in support for JSON
document parsing and serialization
Supports OAuth 1 and 2, including a local redirect listener
Make WebSockets connections against remote services
A fully asynchronous task API based on PPL, including a built-in thread pool

Supports Windows Desktop (7+), Windows Server (2012+), Universal Windows


Platform, Linux, OSX, Android, and iOS.
Windows::Web::Http::HttpClient

A Windows Runtime HTTP client class modeled on the .NET Framework class of the
same name in the System.Web namespace. HttpClient fully supports
asynchronous upload and download over HTTP, and pipeline filters that enable the
insertion of custom HTTP handlers into the pipeline. The Windows SDK includes
sample filters for metered networks, OAuth authentication, and more. For apps
that target only Universal Windows Platform, we recommend that you use the
Windows::Web:HttpClient class.

IXMLHTTPRequest2 interface

Provides a native COM interface that you can use in Windows Runtime apps or
Windows desktop apps to connect to the Internet over HTTP and issue GET, PUT,
and other HTTP commands. For more information, see Walkthrough: Connecting
Using Tasks and XML HTTP Requests.

Windows Internet (WinInet)

Windows API that you can use in Windows desktop apps to connect to the
Internet.

See also
C++ in Visual Studio
Microsoft Azure C and C++ Developer Center
Networks and web services (UWP)
Microsoft C++ porting and upgrading
guide
Article • 10/25/2021

This article provides a guide for upgrading Microsoft C++ code to the latest version of
Visual Studio. For projects created in Visual Studio 2010 through 2017, just open the
project in Visual Studio 2019. You can upgrade a Visual Studio 2008 or earlier project in
two steps. Use Visual Studio 2010 to convert the project to MSBuild format first. Then
open the project in Visual Studio 2019. For complete instructions, see Upgrading C++
projects from earlier versions of Visual Studio.

The toolsets in Visual Studio 2015, Visual Studio 2017, and Visual Studio 2019 are
binary-compatible. Now you can upgrade to a more recent version of the compiler
without having to upgrade your library dependencies. For more information, see C++
binary compatibility between Visual Studio versions.

When upgrading projects that use open-source libraries or are meant to run on multiple
platforms, we recommended migrating to a CMake-based project. For more
information, see CMake projects in Visual Studio

Reasons to upgrade C++ code


If a legacy application is running satisfactorily, in a secure environment, and isn't under
active development, there might not be much incentive to upgrade it. However,
consider an upgrade in these cases: Your application requires ongoing maintenance. Or,
you're doing new feature development, or making performance or security
improvements. An upgrade brings these benefits:

The same code can run faster, because we've improved compiler optimizations.

Modern C++ features and programming practices eliminate many common causes
of bugs, and produce code that's far easier to maintain than older C-style idioms.

Build times are faster, because of performance improvements in the compiler and
linker.

Better standards conformance. The /permissive- compiler option helps you identify
code that doesn't conform to the current C++ standard. The new preprocessor
supports code conformance, too.
Better run-time security, including more secure C Runtime library features. And,
compiler features such as guard checking and address sanitizers (new in Visual
Studio 2019 version 16.4).

Multitargeting vs. upgrading


Perhaps upgrading your code base to a new toolset isn't an option for you. You can still
use the latest Visual Studio to build and edit projects that use older toolsets and
libraries. In Visual Studio 2019, you can take advantage of features such as:

modern static analysis tools, including the C++ Core Guidelines checkers and
Clang-Tidy, to help identify potential problems in your source code.

automatic formatting according to your choice of modern styles can help make
legacy code much more readable.

For more information, see Use native multi-targeting in Visual Studio to build old
projects.

In this section
Title Description

Upgrading How to upgrade your code base to the latest version of Visual Studio and the
C++ projects compiler.
from earlier
versions of
Visual Studio

IDE tools for Useful IDE features that help in the upgrade process.
upgrading
C++ code

C++ binary Consume v140 and later libraries as-is from v140 and later projects.
compatibility
between
Visual Studio
versions

Use native Use Visual Studio with older compilers and libraries.
multi-
targeting in
Visual Studio
to build old
projects
Title Description

Visual C++ A list of all the changes in the Microsoft C++ libraries and build tools from Visual
change Studio 2003 through 2015 that might require changes in your code.
history 2003 -
2015

Visual C++ All the "what's new" information for Microsoft C++ from Visual Studio 2003
What's New through Visual Studio 2015.
2003 through
2015

Porting and For this section, we ported and upgrades several samples and applications and
Upgrading: discussed the experiences and results. These articles give you a sense of what's
Examples and involved in the porting and upgrading process. Throughout the process, we
Case Studies discuss tips and tricks for upgrading and show how specific errors were fixed.

Porting to the Contains information about porting app code to Windows 10 and later
Universal
Windows
Platform

Introduction Provides information for UNIX users who are new to Visual C++ and want to
to Visual C++ become productive with it.
for UNIX
Users

Running Linux Discusses options for migrating UNIX applications to Windows.


programs on
Windows

See also
C++ in Visual Studio
What's New for The C++ compiler in Visual Studio
C++ conformance improvements in Visual Studio
Security Best Practices for C++
Article • 08/03/2021

This article contains information about security tools and practices. Using them does not
make applications immune from attack, but it makes successful attacks less likely.

Visual C++ Security Features


These security features are built into the Microsoft C++ compiler and linker:

/guard (Enable Control Flow Guard)


Causes the compiler to analyze control flow for indirect call targets at compile time, and
then to insert code to verify the targets at runtime.

/GS (Buffer Security Check)


Instructs the compiler to insert overrun detection code into functions that are at risk of
being exploited. When an overrun is detected, execution is stopped. By default, this
option is on.

/SAFESEH (Image has Safe Exception Handlers)


Instructs the linker to include in the output image a table that contains the address of
each exception handler. At run time, the operating system uses this table to make sure
that only legitimate exception handlers are executed. This helps prevent the execution
of exception handlers that are introduced by a malicious attack at run time. By default,
this option is off.

/NXCOMPAT, /NXCOMPAT (Compatible with Data Execution Prevention) These compiler


and linker options enable Data Execution Prevention (DEP) compatibility. DEP guards the
CPU against the execution of non-code pages.

/analyze (Code Analysis)


This compiler option activates code analysis that reports potential security issues such as
buffer overrun, un-initialized memory, null pointer dereferencing, and memory leaks. By
default, this option is off. For more information, see Code Analysis for C/C++ Overview.

/DYNAMICBASE (Use address space layout randomization)


This linker option enables the building of an executable image that can be loaded at
different locations in memory at the beginning of execution. This option also makes the
stack location in memory much less predictable.

Security-Enhanced CRT
The C Runtime Library (CRT) has been augmented to include secure versions of
functions that pose security risks—for example, the unchecked strcpy string copy
function. Because the older, nonsecure versions of these functions are deprecated, they
cause compile-time warnings. We encourage you to use the secure versions of these
CRT functions instead of suppressing the compilation warnings. For more information,
see Security Features in the CRT.

SafeInt Library
SafeInt Library helps prevent integer overflows and other exploitable errors that might
occur when the application performs mathematical operations. The SafeInt library
includes the SafeInt Class, the SafeIntException Class, and several SafeInt Functions.

The SafeInt class protects against integer overflow and divide-by-zero exploits. You can
use it to handle comparisons between values of different types. It provides two error
handling policies. The default policy is for the SafeInt class to throw a
SafeIntException class exception to report why a mathematical operation cannot be
completed. The second policy is for the SafeInt class to stop program execution. You
can also define a custom policy.

Each SafeInt function protects one mathematical operation from an exploitable error.
You can use two different kinds of parameters without converting them to the same
type. To protect multiple mathematical operations, use the SafeInt class.

Checked Iterators
A checked iterator enforces container boundaries. By default, when a checked iterator is
out of bounds, it generates an exception and ends program execution. A checked
iterator provides other levels of response that depend on values that are assigned to
preprocessor defines such as _SECURE_SCL_THROWS and _ITERATOR_DEBUG_LEVEL . For
example, at _ITERATOR_DEBUG_LEVEL=2 , a checked iterator provides comprehensive
correctness checks in debug mode, which are made available by using asserts. For more
information, see Checked Iterators and _ITERATOR_DEBUG_LEVEL.

Code Analysis for Managed Code


Code Analysis for Managed Code, also known as FxCop, checks assemblies for
conformance to the.NET Framework design guidelines. FxCop analyzes the code and
metadata in each assembly to check for defects in the following areas:
Library design

Localization

Naming conventions

Performance

Security

Windows Application Verifier


The Application Verifier (AppVerifier) can help you identify potential application
compatibility, stability, and security issues.

The AppVerifier monitors how an application uses the operating system. It watches the
file system, registry, memory, and APIs while the application is running, and
recommends source-code fixes for issues that it uncovers.

You can use the AppVerifier to:

Test for potential application compatibility errors that are caused by common
programming mistakes.

Examine an application for memory-related issues.

Identify potential security issues in an application.

Windows User Accounts


Using Windows user accounts that belong to the Administrators group exposes
developers and--by extension--customers to security risks. For more information, see
Running as a Member of the Users Group and How User Account Control (UAC) Affects
Your Application.

Guidance for Speculative Execution Side


Channels
For information about how to indentify and mitigate against speculative execution side
channel hardware vulnerabilities in C++ software, see C++ Developer Guidance for
Speculative Execution Side Channels.
See also
System.Security
Security
How User Account Control (UAC) Affects Your Application
Running as a Member of the Users
Group
Article • 08/03/2021

This topic explains how configuring Windows user accounts as a member of the Users
Group (as opposed to the Administrators Group) increases security by reducing the
chances of being infected with malicious code.

Security Risks
Running as an administrator makes your system vulnerable to several kinds of security
attack, such as "Trojan horse" and "buffer overrun." Merely visiting an Internet site as an
administrator can be damaging to the system, as malicious code that is downloaded
from an Internet site may attack your computer. If successful, it inherits your
administrator permissions and can then perform actions such as deleting all your files,
reformatting your hard drive, and creating a new user accounts with administrative
access.

Non Administrator User Groups


The Windows user accounts that developers use normally should be added to either the
Users or Power Users Groups. Developers should also be added to the Debugging
Group. Being a member of the Users group allows you to perform routine tasks
including running programs and visiting Internet sites without exposing your computer
to unnecessary risk. As a member of the Power Users group, you can also perform tasks
such as application installation, printer installation, and most Control Panel operations. If
you need to perform administrative tasks such as upgrading the operating system or
configuring system parameters, you should log into an administrator account for just
long enough to perform the administrative task. Alternatively, the Windows runas
command can be used to launch specific applications with Administrative access.

Exposing Customers to Security Risks


Not being part of the Administrators group is particularly important for developers
because, in addition to protecting development machines, it prevents developers from
inadvertently writing code that requires customers to join the Administrators Group in
order to execute the applications you develop. If code that requires administrator access
is introduced during development, it will fail at runtime, alerting you to the fact that
your application now requires customers to run as Administrators.

Code That Requires Administrator Privileges


Some code requires Administrator access in order to execute. If possible, alternatives to
this code should be pursued. Examples of code operations that require Administrator
access are:

Writing to protected areas of the file system, such as the Windows or Program
Files directories

Writing to protected areas of the registry, such as HKEY_LOCAL_MACHINE

Installing assemblies in the Global Assembly Cache (GAC)

Generally, these actions should be limited to application installation programs. This


allows users to use administrator status only temporarily.

Debugging
You can debug any applications that you launch within Visual Studio (native and
unmanaged) as a non-administrator by becoming part of the Debugging Group. This
includes the ability to attach to a running application using the Attach to Process
command. However, it is necessary to be part of the Administrator Group in order to
debug native or managed applications that were launched by a different user.

See also
Security Best Practices
How User Account Control (UAC)
Affects Your Application
Article • 08/03/2021

User Account Control (UAC) is a feature of Windows Vista in which user accounts have
limited privileges. You can find detailed information about UAC at these sites:

Developer Best Practices and Guidelines for Applications in a Least Privileged


Environment

Building Projects after Enabling UAC


If you build a Visual Studio C++ project on Windows Vista with UAC disabled, and you
later enable UAC, you must clean and rebuild the project for it to work correctly.

Applications that Require Administrative


Privileges
By default, the Visual C++ linker embeds a UAC fragment into the manifest of an
application with an execution level of asInvoker . If your application requires
administrative privileges to run correctly (for example, if it modifies the HKLM node of
the registry or if it writes to protected areas of the disk, such as the Windows directory),
you must modify your application.

The first option is to modify the UAC fragment of the manifest to change the execution
level to requireAdministrator. The application will then prompt the user for
administrative credentials before it runs. For information about how to do this, see
/MANIFESTUAC (Embeds UAC information in manifest).

The second option is to not embed a UAC fragment into the manifest by specifying the
/MANIFESTUAC:NO linker option. In this case, your application will run virtualized. Any
changes you make to the registry or to the file system will not persist after your
application has ended.

The following flowchart describes how your application will run depending on whether
UAC is enabled and whether the application has a UAC manifest:
See also
Security Best Practices
C++ Developer Guidance for
Speculative Execution Side Channels
Article • 08/03/2021

This article contains guidance for developers to assist with identifying and mitigating
speculative execution side channel hardware vulnerabilities in C++ software. These
vulnerabilities can disclose sensitive information across trust boundaries and can affect
software that runs on processors that support speculative, out-of-order execution of
instructions. This class of vulnerabilities was first described in January, 2018 and
additional background and guidance can be found in Microsoft's security advisory .

The guidance provided by this article is related to the classes of vulnerabilities


represented by:

1. CVE-2017-5753, also known as Spectre variant 1. This hardware vulnerability class


is related to side channels that can arise due to speculative execution that occurs
as a result of a conditional branch misprediction. The Microsoft C++ compiler in
Visual Studio 2017 (starting with version 15.5.5) includes support for the /Qspectre
switch which provides a compile-time mitigation for a limited set of potentially
vulnerable coding patterns related to CVE-2017-5753. The /Qspectre switch is also
available in Visual Studio 2015 Update 3 through KB 4338871 . The
documentation for the /Qspectre flag provides more information on its effects and
usage.

2. CVE-2018-3639, also known as Speculative Store Bypass (SSB) . This hardware


vulnerability class is related to side channels that can arise due to speculative
execution of a load ahead of a dependent store as a result of a memory access
misprediction.

An accessible introduction to speculative execution side channel vulnerabilities can be


found in the presentation titled The Case of Spectre and Meltdown by one of the
research teams that discovered these issues.

What are Speculative Execution Side Channel


hardware vulnerabilities?
Modern CPUs provide higher degrees of performance by making use of speculative and
out-of-order execution of instructions. For example, this is often accomplished by
predicting the target of branches (conditional and indirect) which enables the CPU to
begin speculatively executing instructions at the predicted branch target, thus avoiding
a stall until the actual branch target is resolved. In the event that the CPU later discovers
that a misprediction occurred, all of the machine state that was computed speculatively
is discarded. This ensures that there are no architecturally visible effects of the
mispredicted speculation.

While speculative execution does not affect the architecturally visible state, it can leave
residual traces in non-architectural state, such as the various caches that are used by the
CPU. It is these residual traces of speculative execution that can give rise to side channel
vulnerabilities. To better understand this, consider the following code fragment which
provides an example of CVE-2017-5753 (Bounds Check Bypass):

C++

// A pointer to a shared memory region of size 1MB (256 * 4096)


unsigned char *shared_buffer;

unsigned char ReadByte(unsigned char *buffer, unsigned int buffer_size,


unsigned int untrusted_index) {
if (untrusted_index < buffer_size) {
unsigned char value = buffer[untrusted_index];
return shared_buffer[value * 4096];
}
}

In this example, ReadByte is supplied a buffer, a buffer size, and an index into that
buffer. The index parameter, as specified by untrusted_index , is supplied by a less
privileged context, such as a non-administrative process. If untrusted_index is less than
buffer_size , then the character at that index is read from buffer and used to index into
a shared region of memory referred to by shared_buffer .

From an architectural perspective, this code sequence is perfectly safe as it is


guaranteed that untrusted_index will always be less than buffer_size . However, in the
presence of speculative execution, it is possible that the CPU will mispredict the
conditional branch and execute the body of the if statement even when
untrusted_index is greater than or equal to buffer_size . As a consequence of this, the

CPU may speculatively read a byte from beyond the bounds of buffer (which could be
a secret) and could then use that byte value to compute the address of a subsequent
load through shared_buffer .

While the CPU will eventually detect this misprediction, residual side effects may be left
in the CPU cache that reveal information about the byte value that was read out of
bounds from buffer . These side effects can be detected by a less privileged context
running on the system by probing how quickly each cache line in shared_buffer is
accessed. The steps that can be taken to accomplish this are:

1. Invoke ReadByte multiple times with untrusted_index being less than


buffer_size . The attacking context can cause the victim context to invoke
ReadByte (e.g. via RPC) such that the branch predictor is trained to be not-taken as

untrusted_index is less than buffer_size .

2. Flush all cache lines in shared_buffer . The attacking context must flush all of the
cache lines in the shared region of memory referred to by shared_buffer . Since the
memory region is shared, this is straightforward and can be accomplished using
intrinsics such as _mm_clflush .

3. Invoke ReadByte with untrusted_index being greater than buffer_size . The


attacking context causes the victim context to invoke ReadByte such that it
incorrectly predicts that the branch will not be taken. This causes the processor to
speculatively execute the body of the if block with untrusted_index being greater
than buffer_size , thus leading to an out-of-bounds read of buffer . Consequently,
shared_buffer is indexed using a potentially secret value that was read out-of-

bounds, thus causing the respective cache line to be loaded by the CPU.

4. Read each cache line in shared_buffer to see which is accessed most quickly. The
attacking context can read each cache line in shared_buffer and detect the cache
line that loads significantly faster than the others. This is the cache line that is likely
to have been brought in by step 3. Since there is a 1:1 relationship between byte
value and cache line in this example, this allows the attacker to infer the actual
value of the byte that was read out-of-bounds.

The above steps provide an example of using a technique known as FLUSH+RELOAD in


conjunction with exploiting an instance of CVE-2017-5753.

What software scenarios can be impacted?


Developing secure software using a process like the Security Development Lifecycle
(SDL) typically requires developers to identify the trust boundaries that exist in their
application. A trust boundary exists in places where an application may interact with
data provided by a less-trusted context, such as another process on the system or a
non-administrative user mode process in the case of a kernel-mode device driver. The
new class of vulnerabilities involving speculative execution side channels is relevant to
many of the trust boundaries in existing software security models that isolate code and
data on a device.
The following table provides a summary of the software security models where
developers may need to be concerned about these vulnerabilities occurring:

Trust Description
boundary

Virtual Applications that isolate workloads in separate virtual machines that receive
machine untrusted data from another virtual machine may be at risk.
boundary

Kernel A kernel-mode device driver that receives untrusted data from a non-administrative
boundary user mode process may be at risk.

Process An application that receives untrusted data from another process running on the
boundary local system, such as through a Remote Procedure Call (RPC), shared memory, or
other Inter-Process Communication (IPC) mechanisms may be at risk.

Enclave An application that executes within a secure enclave (such as Intel SGX) that receives
boundary untrusted data from outside of the enclave may be at risk.

Language An application that interprets or Just-In-Time (JIT) compiles and executes untrusted
boundary code written in a higher-level language may be at risk.

Applications that have attack surface exposed to any of the above trust boundaries
should review code on the attack surface to identify and mitigate possible instances of
speculative execution side channel vulnerabilities. It should be noted that trust
boundaries exposed to remote attack surfaces, such as remote network protocols, have
not been demonstrated to be at risk to speculative execution side channel
vulnerabilities.

Potentially vulnerable coding patterns


Speculative execution side channel vulnerabilities can arise as a consequence of multiple
coding patterns. This section describes potentially vulnerable coding patterns and
provides examples for each, but it should be recognized that variations on these themes
may exist. As such, developers are advised to take these patterns as examples and not as
an exhaustive list of all potentially vulnerable coding patterns. The same classes of
memory safety vulnerabilities that can exist in software today may also exist along
speculative and out-of-order paths of execution, including but not limited to buffer
overruns, out-of-bounds array accesses, uninitialized memory use, type confusion, and
so on. The same primitives that attackers can use to exploit memory safety
vulnerabilities along architectural paths may also apply to speculative paths.

In general, speculative execution side channels related to conditional branch


misprediction can arise when a conditional expression operates on data that can be
controlled or influenced by a less-trusted context. For example, this can include
conditional expressions used in if , for , while , switch , or ternary statements. For each
of these statements, the compiler may generate a conditional branch that the CPU may
then predict the branch target for at runtime.

For each example, a comment with the phrase "SPECULATION BARRIER" is inserted
where a developer could introduce a barrier as a mitigation. This is discussed in more
detail in the section on mitigations.

Speculative out-of-bounds load


This category of coding patterns involves a conditional branch misprediction that leads
to a speculative out-of-bounds memory access.

Array out-of-bounds load feeding a load


This coding pattern is the originally described vulnerable coding pattern for CVE-2017-
5753 (Bounds Check Bypass). The background section of this article explains this pattern
in detail.

C++

// A pointer to a shared memory region of size 1MB (256 * 4096)


unsigned char *shared_buffer;

unsigned char ReadByte(unsigned char *buffer, unsigned int buffer_size,


unsigned int untrusted_index) {
if (untrusted_index < buffer_size) {
// SPECULATION BARRIER
unsigned char value = buffer[untrusted_index];
return shared_buffer[value * 4096];
}
}

Similarly, an array out-of-bounds load may occur in conjunction with a loop that
exceeds its terminating condition due to a misprediction. In this example, the
conditional branch associated with the x < buffer_size expression may mispredict and
speculatively execute the body of the for loop when x is greater than or equal to
buffer_size , thus resulting in a speculative out-of-bounds load.

C++

// A pointer to a shared memory region of size 1MB (256 * 4096)


unsigned char *shared_buffer;
unsigned char ReadBytes(unsigned char *buffer, unsigned int buffer_size) {
for (unsigned int x = 0; x < buffer_size; x++) {
// SPECULATION BARRIER
unsigned char value = buffer[x];
return shared_buffer[value * 4096];
}
}

Array out-of-bounds load feeding an indirect branch


This coding pattern involves the case where a conditional branch misprediction can lead
to an out-of-bounds access to an array of function pointers which then leads to an
indirect branch to the target address that was read out-of-bounds. The following
snippet provides an example that demonstrates this.

In this example, an untrusted message identifier is provided to DispatchMessage


through the untrusted_message_id parameter. If untrusted_message_id is less than
MAX_MESSAGE_ID , then it is used to index into an array of function pointers and branch to

the corresponding branch target. This code is safe architecturally, but if the CPU
mispredicts the conditional branch, it could result in DispatchTable being indexed by
untrusted_message_id when its value is greater than or equal to MAX_MESSAGE_ID , thus

leading to an out-of-bounds access. This could result in speculative execution from a


branch target address that is derived beyond the bounds of the array which could lead
to information disclosure depending on the code that is executed speculatively.

C++

#define MAX_MESSAGE_ID 16

typedef void (*MESSAGE_ROUTINE)(unsigned char *buffer, unsigned int


buffer_size);

const MESSAGE_ROUTINE DispatchTable[MAX_MESSAGE_ID];

void DispatchMessage(unsigned int untrusted_message_id, unsigned char


*buffer, unsigned int buffer_size) {
if (untrusted_message_id < MAX_MESSAGE_ID) {
// SPECULATION BARRIER
DispatchTable[untrusted_message_id](buffer, buffer_size);
}
}

As with the case of an array out-of-bounds load feeding another load, this condition
may also arise in conjunction with a loop that exceeds its terminating condition due to a
misprediction.
Array out-of-bounds store feeding an indirect branch
While the previous example showed how a speculative out-of-bounds load can
influence an indirect branch target, it is also possible for an out-of-bounds store to
modify an indirect branch target, such as a function pointer or a return address. This can
potentially lead to speculative execution from an attacker-specified address.

In this example, an untrusted index is passed through the untrusted_index parameter. If


untrusted_index is less than the element count of the pointers array (256 elements),
then the provided pointer value in ptr is written to the pointers array. This code is safe
architecturally, but if the CPU mispredicts the conditional branch, it could result in ptr
being speculatively written beyond the bounds of the stack-allocated pointers array.
This could lead to speculative corruption of the return address for WriteSlot . If an
attacker can control the value of ptr , they may be able to cause speculative execution
from an arbitrary address when WriteSlot returns along the speculative path.

C++

unsigned char WriteSlot(unsigned int untrusted_index, void *ptr) {


void *pointers[256];
if (untrusted_index < 256) {
// SPECULATION BARRIER
pointers[untrusted_index] = ptr;
}
}

Similarly, if a function pointer local variable named func were allocated on the stack,
then it may be possible to speculatively modify the address that func refers to when the
conditional branch misprediction occurs. This could result in speculative execution from
an arbitrary address when the function pointer is called through.

C++

unsigned char WriteSlot(unsigned int untrusted_index, void *ptr) {


void *pointers[256];
void (*func)() = &callback;
if (untrusted_index < 256) {
// SPECULATION BARRIER
pointers[untrusted_index] = ptr;
}
func();
}

It should be noted that both of these examples involve speculative modification of


stack-allocated indirect branch pointers. It is possible that speculative modification
could also occur for global variables, heap-allocated memory, and even read-only
memory on some CPUs. For stack-allocated memory, the Microsoft C++ compiler
already takes steps to make it more difficult to speculatively modify stack-allocated
indirect branch targets, such as by reordering local variables such that buffers are placed
adjacent to a security cookie as part of the /GS compiler security feature.

Speculative type confusion


This category deals with coding patterns that can give rise to a speculative type
confusion. This occurs when memory is accessed using an incorrect type along a non-
architectural path during speculative execution. Both conditional branch misprediction
and speculative store bypass can potentially lead to a speculative type confusion.

For speculative store bypass, this could occur in scenarios where a compiler reuses a
stack location for variables of multiple types. This is because the architectural store of a
variable of type A may be bypassed, thus allowing the load of type A to speculatively
execute before the variable is assigned. If the previously stored variable is of a different
type, then this can create the conditions for a speculative type confusion.

For conditional branch misprediction, the following code snippet will be used to
describe different conditions that speculative type confusion can give rise to.

C++

enum TypeName {
Type1,
Type2
};

class CBaseType {
public:
CBaseType(TypeName type) : type(type) {}
TypeName type;
};

class CType1 : public CBaseType {


public:
CType1() : CBaseType(Type1) {}
char field1[256];
unsigned char field2;
};

class CType2 : public CBaseType {


public:
CType2() : CBaseType(Type2) {}
void (*dispatch_routine)();
unsigned char field2;
};

// A pointer to a shared memory region of size 1MB (256 * 4096)


unsigned char *shared_buffer;

unsigned char ProcessType(CBaseType *obj)


{
if (obj->type == Type1) {
// SPECULATION BARRIER
CType1 *obj1 = static_cast<CType1 *>(obj);

unsigned char value = obj1->field2;

return shared_buffer[value * 4096];


}
else if (obj->type == Type2) {
// SPECULATION BARRIER
CType2 *obj2 = static_cast<CType2 *>(obj);

obj2->dispatch_routine();

return obj2->field2;
}
}

Speculative type confusion leading to an out-of-bounds


load
This coding pattern involves the case where a speculative type confusion can result in an
out-of-bounds or type-confused field access where the loaded value feeds a subsequent
load address. This is similar to the array out-of-bounds coding pattern but it is
manifested through an alternative coding sequence as shown above. In this example, an
attacking context could cause the victim context to execute ProcessType multiple times
with an object of type CType1 ( type field is equal to Type1 ). This will have the effect of
training the conditional branch for the first if statement to predict not taken. The
attacking context can then cause the victim context to execute ProcessType with an
object of type CType2 . This can result in a speculative type confusion if the conditional
branch for the first if statement mispredicts and executes the body of the if
statement, thus casting an object of type CType2 to CType1 . Since CType2 is smaller than
CType1 , the memory access to CType1::field2 will result in a speculative out-of-bounds

load of data that may be secret. This value is then used in a load from shared_buffer
which can create observable side effects, as with the array out-of-bounds example
described previously.

Speculative type confusion leading to an indirect branch


This coding pattern involves the case where a speculative type confusion can result in an
unsafe indirect branch during speculative execution. In this example, an attacking
context could cause the victim context to execute ProcessType multiple times with an
object of type CType2 ( type field is equal to Type2 ). This will have the effect of training
the conditional branch for the first if statement to be taken and the else if statement
to be not taken. The attacking context can then cause the victim context to execute
ProcessType with an object of type CType1 . This can result in a speculative type
confusion if the conditional branch for the first if statement predicts taken and the
else if statement predicts not taken, thus executing the body of the else if and
casting an object of type CType1 to CType2 . Since the CType2::dispatch_routine field
overlaps with the char array CType1::field1 , this could result in a speculative indirect
branch to an unintended branch target. If the attacking context can control the byte
values in the CType1::field1 array, they may be able to control the branch target
address.

Speculative uninitialized use


This category of coding patterns involves scenarios where speculative execution may
access uninitialized memory and use it to feed a subsequent load or indirect branch. For
these coding patterns to be exploitable, an attacker needs to be able to control or
meaningfully influence the contents of the memory that is used without being initialized
by the context that it is being used in.

Speculative uninitialized use leading to an out-of-bounds


load
A speculative uninitialized use can potentially lead to an out-of-bounds load using an
attacker controlled value. In the example below, the value of index is assigned
trusted_index on all architectural paths and trusted_index is assumed to be less than
or equal to buffer_size . However, depending on the code produced by the compiler, it
is possible that a speculative store bypass may occur that allows the load from
buffer[index] and dependent expressions to execute ahead of the assignment to

index . If this occurs, an uninitialized value for index will be used as the offset into

buffer which could enable an attacker to read sensitive information out-of-bounds and
convey this through a side channel through the dependent load of shared_buffer .

C++

// A pointer to a shared memory region of size 1MB (256 * 4096)


unsigned char *shared_buffer;
void InitializeIndex(unsigned int trusted_index, unsigned int *index) {
*index = trusted_index;
}

unsigned char ReadByte(unsigned char *buffer, unsigned int buffer_size,


unsigned int trusted_index) {
unsigned int index;

InitializeIndex(trusted_index, &index); // not inlined

// SPECULATION BARRIER
unsigned char value = buffer[index];
return shared_buffer[value * 4096];
}

Speculative uninitialized use leading to an indirect branch


A speculative uninitialized use can potentially lead to an indirect branch where the
branch target is controlled by an attacker. In the example below, routine is assigned to
either DefaultMessageRoutine1 or DefaultMessageRoutine depending on the value of
mode . On the architectural path, this will result in routine always being initialized ahead

of the indirect branch. However, depending on the code produced by the compiler, a
speculative store bypass may occur that allows the indirect branch through routine to
be speculatively executed ahead of the assignment to routine . If this occurs, an attacker
may be able to speculatively execute from an arbitrary address, assuming the attacker
can influence or control the uninitialized value of routine .

C++

#define MAX_MESSAGE_ID 16

typedef void (*MESSAGE_ROUTINE)(unsigned char *buffer, unsigned int


buffer_size);

const MESSAGE_ROUTINE DispatchTable[MAX_MESSAGE_ID];


extern unsigned int mode;

void InitializeRoutine(MESSAGE_ROUTINE *routine) {


if (mode == 1) {
*routine = &DefaultMessageRoutine1;
}
else {
*routine = &DefaultMessageRoutine;
}
}

void DispatchMessage(unsigned int untrusted_message_id, unsigned char


*buffer, unsigned int buffer_size) {
MESSAGE_ROUTINE routine;

InitializeRoutine(&routine); // not inlined

// SPECULATION BARRIER
routine(buffer, buffer_size);
}

Mitigation options
Speculative execution side channel vulnerabilities can be mitigated by making changes
to source code. These changes can involve mitigating specific instances of a
vulnerability, such as by adding a speculation barrier, or by making changes to the
design of an application to make sensitive information inaccessible to speculative
execution.

Speculation barrier via manual instrumentation


A speculation barrier can be manually inserted by a developer to prevent speculative
execution from proceeding along a non-architectural path. For example, a developer can
insert a speculation barrier before a dangerous coding pattern in the body of a
conditional block, either at the beginning of the block (after the conditional branch) or
before the first load that is of concern. This will prevent a conditional branch
misprediction from executing the dangerous code on a non-architectural path by
serializing execution. The speculation barrier sequence differs by hardware architecture
as described by the following table:

Architecture Speculation barrier intrinsic for CVE- Speculation barrier intrinsic for CVE-
2017-5753 2018-3639

x86/x64 _mm_lfence() _mm_lfence()

ARM not currently available __dsb(0)

ARM64 not currently available __dsb(0)

For example, the following code pattern can be mitigated by using the _mm_lfence
intrinsic as shown below.

C++

// A pointer to a shared memory region of size 1MB (256 * 4096)


unsigned char *shared_buffer;
unsigned char ReadByte(unsigned char *buffer, unsigned int buffer_size,
unsigned int untrusted_index) {
if (untrusted_index < buffer_size) {
_mm_lfence();
unsigned char value = buffer[untrusted_index];
return shared_buffer[value * 4096];
}
}

Speculation barrier via compiler-time instrumentation


The Microsoft C++ compiler in Visual Studio 2017 (starting with version 15.5.5) includes
support for the /Qspectre switch which automatically inserts a speculation barrier for a
limited set of potentially vulnerable coding patterns related to CVE-2017-5753. The
documentation for the /Qspectre flag provides more information on its effects and
usage. It is important to note that this flag does not cover all of the potentially
vulnerable coding patterns and as such developers should not rely on it as a
comprehensive mitigation for this class of vulnerabilities.

Masking array indices


In cases where a speculative out-of-bounds load may occur, the array index can be
strongly bounded on both the architectural and non-architectural path by adding logic
to explicitly bound the array index. For example, if an array can be allocated to a size
that is aligned to a power of two, then a simple mask can be introduced. This is
illustrated in the sample below where it is assumed that buffer_size is aligned to a
power of two. This ensures that untrusted_index is always less than buffer_size , even if
a conditional branch misprediction occurs and untrusted_index was passed in with a
value greater than or equal to buffer_size .

It should be noted that the index masking performed here could be subject to
speculative store bypass depending on the code that is generated by the compiler.

C++

// A pointer to a shared memory region of size 1MB (256 * 4096)


unsigned char *shared_buffer;

unsigned char ReadByte(unsigned char *buffer, unsigned int buffer_size,


unsigned int untrusted_index) {
if (untrusted_index < buffer_size) {
untrusted_index &= (buffer_size - 1);
unsigned char value = buffer[untrusted_index];
return shared_buffer[value * 4096];
}
}

Removing sensitive information from memory


Another technique that can be used to mitigate speculative execution side channel
vulnerabilities is to remove sensitive information from memory. Software developers can
look for opportunities to refactor their application such that sensitive information is not
accessible during speculative execution. This can be accomplished by refactoring the
design of an application to isolate sensitive information into separate processes. For
example, a web browser application can attempt to isolate the data associated with each
web origin into separate processes, thus preventing one process from being able to
access cross-origin data through speculative execution.

See also
Guidance to mitigate speculative execution side-channel vulnerabilities
Mitigating speculative execution side channel hardware vulnerabilities
C/C++ language and standard libraries
reference
Article • 09/12/2024

This section of the documentation contains reference content for the Microsoft
implementation of the ISO standard C and C++ languages. The language reference
includes documentation for the preprocessor, compiler intrinsics, and supported
assembly languages.

You'll also find documentation for the C runtime library, the C++ standard library, and
several other libraries available with the Microsoft C/C++ compiler (MSVC) here.

Language reference
C language
Reference content for the Microsoft implementation of the C language.

C++ language
Reference content for the Microsoft implementation of the C++ language.

C/C++ preprocessor
Reference content for the preprocessor used by C and C++.

Compiler intrinsics
Describes intrinsic functions that are available in Microsoft C and C++ for x86, ARM,
ARM64, and x64 architectures.

Inline assembler
Explains how to use the Visual C/C++ inline assembler with x86 processors.

ARM assembler reference


Provides reference material for the Microsoft ARM assembler (ARMASM) and related
tools.

Microsoft macro assembler reference


Provides reference material for the Microsoft Macro assembler (MASM).

Libraries reference

Standard libraries
C runtime library
The reference for the Microsoft implementation of the C runtime library (CRT),
sometimes referred to as the Universal CRT.

C++ standard library


The reference for the Microsoft implementation of the C++ standard library.

Libraries for Windows applications


MFC/ATL
Documentation for the Microsoft Foundation Classes (MFC) and Active Template Library
(ATL) class libraries.

Additional libraries
C++ AMP (C++ Accelerated Massive Parallelism)
Classes that enable the use of modern graphics processors for general purpose
programming.

Concurrency Runtime
Classes that simplify the writing of programs that use data parallelism or task
parallelism.

OpenMP
Reference for the Microsoft implementation of the OpenMP API.

Proxy library
A header-only C++20 library for using polymorphism in C++ without inheritance. For
API reference information, see Proxy 3 Specifications

SafeInt library
A portable library that can be used with MSVC, GCC, or Clang to help prevent integer
overflows.

Data Access Libraries Libraries to support data access using ATL or MFC, and legacy
services such as OLE DB and ODBC.

Related articles
Windows Runtime (WinRT) with C++
C++/WinRT is an entirely standard modern C++17 language projection for Windows
Runtime (WinRT) APIs, implemented as a header-file-based library.
Windows Runtime C++ Template Library (WRL)
A legacy template library for the Windows Runtime, replaced by C++/WinRT.

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Languages
Article • 08/03/2021

C Language
C++ Language
C/C++ Preprocessor
Compiler Intrinsics and Assembly Language
C Language Reference
Article • 08/03/2021

The C Language Reference describes the C programming language as implemented in


Microsoft C. The book's organization is based on the ANSI C standard (sometimes
referred to as C89) with additional material on the Microsoft extensions to the ANSI C
standard.

Organization of the C Language Reference

For additional reference material on C++ and the preprocessor, see:

C++ Language Reference

Preprocessor Reference

Compiler and linker options are documented in the C/C++ Building Reference.

See also
C++ Language Reference
C++ Language Reference
Article • 08/03/2021

This reference explains the C++ programming language as implemented in the


Microsoft C++ compiler. The organization is based on The Annotated C++ Reference
Manual by Margaret Ellis and Bjarne Stroustrup and on the ANSI/ISO C++ International
Standard (ISO/IEC FDIS 14882). Microsoft-specific implementations of C++ language
features are included.

For an overview of Modern C++ programming practices, see Welcome Back to C++.

See the following tables to quickly find a keyword or operator:

C++ Keywords

C++ Operators

In This Section
Lexical Conventions
Fundamental lexical elements of a C++ program: tokens, comments, operators,
keywords, punctuators, literals. Also, file translation, operator precedence/associativity.

Basic Concepts
Scope, linkage, program startup and termination, storage classes, and types.

Built-in types The fundamental types that are built into the C++ compiler and their
value ranges.

Standard Conversions
Type conversions between built-in types. Also, arithmetic conversions and conversions
among pointer, reference, and pointer-to-member types.

Declarations and definitions Declaring and defining variables, types and functions.

Operators, Precedence and Associativity


The operators in C++.

Expressions
Types of expressions, semantics of expressions, reference topics on operators, casting
and casting operators, run-time type information.
Lambda Expressions
A programming technique that implicitly defines a function object class and constructs a
function object of that class type.

Statements
Expression, null, compound, selection, iteration, jump, and declaration statements.

Classes and structs


Introduction to classes, structures, and unions. Also, member functions, special member
functions, data members, bit fields, this pointer, nested classes.

Unions
User-defined types in which all members share the same memory location.

Derived Classes
Single and multiple inheritance, virtual functions, multiple base classes, abstract
classes, scope rules. Also, the __super and __interface keywords.

Member-Access Control
Controlling access to class members: public , private , and protected keywords. Friend
functions and classes.

Overloading
Overloaded operators, rules for operator overloading.

Exception Handling
C++ exception handling, structured exception handling (SEH), keywords used in writing
exception handling statements.

Assertion and User-Supplied Messages


#error directive, the static_assert keyword, the assert macro.

Templates
Template specifications, function templates, class templates, typename keyword,
templates vs. macros, templates and smart pointers.

Event Handling
Declaring events and event handlers.

Microsoft-Specific Modifiers
Modifiers specific to Microsoft C++. Memory addressing, calling conventions, naked
functions, extended storage-class attributes ( __declspec ), __w64 .
Inline Assembler
Using assembly language and C++ in __asm blocks.

Compiler COM Support


A reference to Microsoft-specific classes and global functions used to support COM
types.

Microsoft Extensions
Microsoft extensions to C++.

Nonstandard Behavior
Information about nonstandard behavior of the Microsoft C++ compiler.

Welcome Back to C++


An overview of modern C++ programming practices for writing safe, correct and
efficient programs.

Related Sections
Component Extensions for Runtime Platforms
Reference material on using the Microsoft C++ compiler to target .NET.

C/C++ Building Reference


Compiler options, linker options, and other build tools.

C/C++ Preprocessor Reference


Reference material on pragmas, preprocessor directives, predefined macros, and the
preprocessor.

Visual C++ Libraries


A list of links to the reference start pages for the various Microsoft C++ libraries.

See also
C Language Reference
C/C++ preprocessor reference
Article • 08/03/2021

The C/C++ preprocessor reference explains the preprocessor as it is implemented in


Microsoft C/C++. The preprocessor performs preliminary operations on C and C++ files
before they are passed to the compiler. You can use the preprocessor to conditionally
compile code, insert files, specify compile-time error messages, and apply machine-
specific rules to sections of code.

In Visual Studio 2019 the /Zc:preprocessor compiler option provides a fully conformant
C11 and C17 preprocessor. This is the default when you use the compiler flag /std:c11
or /std:c17 .

In this section
Preprocessor
Provides an overview of the traditional and new conforming preprocessors.

Preprocessor directives
Describes directives, typically used to make source programs easy to change and easy to
compile in different execution environments.

Preprocessor operators
Discusses the four preprocessor-specific operators used in the context of the #define
directive.

Predefined macros
Discusses predefined macros as specified by the C and C++ standards and by Microsoft
C++.

Pragmas
Discusses pragmas, which offer a way for each compiler to offer machine- and operating
system-specific features while retaining overall compatibility with the C and C++
languages.

Related sections
C++ language reference
Provides reference material for the Microsoft implementation of the C++ language.
C language reference
Provides reference material for the Microsoft implementation of the C language.

C/C++ build reference


Provides links to topics discussing compiler and linker options.

Visual Studio projects - C++


Describes the user interface in Visual Studio that enables you to specify the directories
that the project system will search to locate files for your C++ project.
Compiler intrinsics and assembly
language
Article • 08/03/2021

This section of the documentation contains information about compiler intrinsics and
the assembly language.

Related articles
Title Description

Compiler intrinsics Describes intrinsic functions that are available in Microsoft C and C++
for x86, ARM, and x64 architectures.

Inline assembler Explains how to use the Visual C/C++ inline assembler with x86
processors.

ARM assembler Provides reference material for the Microsoft ARM assembler (armasm)
reference and related tools.

Microsoft Macro Provides reference material for the Microsoft Macro assembler (masm).
Assembler reference

C++ in Visual Studio The top-level article for Visual C++ documentation.
Compiler intrinsics
Article • 08/03/2021

Most functions are contained in libraries, but some functions are built in (that is,
intrinsic) to the compiler. These are referred to as intrinsic functions or intrinsics.

Remarks
If a function is an intrinsic, the code for that function is usually inserted inline, avoiding
the overhead of a function call and allowing highly efficient machine instructions to be
emitted for that function. An intrinsic is often faster than the equivalent inline assembly,
because the optimizer has a built-in knowledge of how many intrinsics behave, so some
optimizations can be available that are not available when inline assembly is used. Also,
the optimizer can expand the intrinsic differently, align buffers differently, or make other
adjustments depending on the context and arguments of the call.

The use of intrinsics affects the portability of code, because intrinsics that are available
in Visual C++ might not be available if the code is compiled with other compilers and
some intrinsics that might be available for some target architectures are not available
for all architectures. However, intrinsics are usually more portable than inline assembly.
The intrinsics are required on 64-bit architectures where inline assembly is not
supported.

Some intrinsics, such as __assume and __ReadWriteBarrier , provide information to the


compiler, which affects the behavior of the optimizer.

Some intrinsics are available only as intrinsics, and some are available both in function
and intrinsic implementations. You can instruct the compiler to use the intrinsic
implementation in one of two ways, depending on whether you want to enable only
specific functions or you want to enable all intrinsics. The first way is to use #pragma
intrinsic( intrinsic-function-name-list ) . The pragma can be used to specify a single
intrinsic or multiple intrinsics separated by commas. The second is to use the /Oi
(Generate intrinsic functions) compiler option, which makes all intrinsics on a given
platform available. Under /Oi, use #pragma function( intrinsic-function-name-list ) to
force a function call to be used instead of an intrinsic. If the documentation for a specific
intrinsic notes that the routine is only available as an intrinsic, then the intrinsic
implementation is used regardless of whether /Oi or #pragma intrinsic is specified. In
all cases, /Oi or #pragma intrinsic allows, but does not force, the optimizer to use the
intrinsic. The optimizer can still call the function.
Some standard C/C++ library functions are available in intrinsic implementations on
some architectures. When calling a CRT function, the intrinsic implementation is used if
/Oi is specified on the command line.

A header file, <intrin.h>, is available that declares prototypes for the common intrinsic
functions. Manufacturer-specific intrinsics are available in the <immintrin.h> and
<ammintrin.h> header files. Additionally, certain Windows headers declare functions
that map onto a compiler intrinsic.

The following sections list all intrinsics that are available on various architectures. For
more information on how the intrinsics work on your particular target processor, refer to
the manufacturer's reference documentation.

ARM intrinsics

ARM64 intrinsics

x86 intrinsics list

x64 (amd64) Intrinsics List

Intrinsics available on all architectures

Alphabetical listing of intrinsic functions

See also
ARM assembler reference
Microsoft Macro Assembler reference
Keywords
C run-time library reference
ARM Assembler reference
Article • 05/10/2022

The articles in this section of the documentation provide reference material for the
Microsoft ARM assembler (armasm or armasm64) and related tools.

Related articles
Title Description

ARM Assembler Describes the Microsoft armasm and armasm64 command-line


command-line reference options.

ARM Assembler Describes commonly seen armasm and armasm64 warning and error
diagnostic messages messages.

ARM Assembler Describes the ARM directives that are different in Microsoft armasm
directives and armasm64.

ARM Architecture Choose the relevant manual for your ARM architecture. Each contains
Reference Manual on reference sections about ARM, Thumb, NEON, and VFP, and additional
the ARM Developer information about the ARM assembly language.
website.

ARM Compiler armasm Choose a recent version to find up-to-date information about the
User Guide on the ARM assembly language.
ARM Developer website.

) Important

The armasm assembler that the ARM Developer website describes isn't the same as
the Microsoft armasm assembler that's included in Visual Studio and is
documented in this section.

See also
ARM intrinsics
ARM64 intrinsics
Compiler intrinsics
Inline Assembler
Article • 08/03/2021

Microsoft Specific

Assembly language serves many purposes, such as improving program speed, reducing
memory needs, and controlling hardware. You can use the inline assembler to embed
assembly-language instructions directly in your C and C++ source programs without
extra assembly and link steps. The inline assembler is built into the compiler, so you
don't need a separate assembler such as the Microsoft Macro Assembler (MASM).

7 Note

Programs with inline assembler code are not fully portable to other hardware
platforms. If you are designing for portability, avoid using inline assembler.

Inline assembly is not supported on the ARM and x64 processors. The following topics
explain how to use the Visual C/C++ inline assembler with x86 processors:

Inline Assembler Overview

Advantages of Inline Assembly

__asm

Using Assembly Language in __asm Blocks

Using C or C++ in __asm Blocks

Using and Preserving Registers in Inline Assembly

Jumping to Labels in Inline Assembly

Calling C Functions in Inline Assembly

Calling C++ Functions in Inline Assembly

Defining __asm Blocks as C Macros

Optimizing Inline Assembly

END Microsoft Specific


See also
Compiler Intrinsics and Assembly Language
C++ Language Reference
Microsoft Macro Assembler reference
Article • 09/22/2021

The Microsoft Macro Assembler (MASM) provides several advantages over inline
assembly. MASM contains a macro language that has features such as looping,
arithmetic, and text string processing. MASM gives you greater control over the
hardware. By using MASM, you also can reduce time and memory overhead in your
code.

In This Section
ML and ML64 command-line option
Describes the ML and ML64 command-line options.

MASM for x64 (ml64.exe)


Information about how to create output files for x64.

Instruction Format
Describes basic instruction format and instruction prefixes for MASM.

Directives reference
Provides links to articles that discuss the use of directives in MASM.

Symbols Reference
Provides links to articles that discuss the use of symbols in MASM.

Operators Reference
Provides links to articles that discuss the use of operators in MASM.

ML error messages
Describes fatal and nonfatal error messages and warnings.

Processor Manufacturer Programming Manuals


Provides links to programming information about processors not manufactured, sold, or
supported by Microsoft.

MASM BNF Grammar

Formal BNF description of MASM for x64.

Related Sections
C++ in Visual Studio
Provides links to different areas of the Visual Studio and Visual C++ documentation.

See also
Compiler Intrinsics
x86 Intrinsics
x64 (amd64) Intrinsics
Component Extensions for .NET and
UWP
Article • 09/21/2021

The C++ standard allows compiler vendors to provide non-standard extensions to the
language. Microsoft provides extensions to help you connect native C++ code to code
that runs on the .NET Framework or the Universal Windows Platform (UWP). The .NET
extensions are called C++/CLI and produce code that executes in the .NET managed
execution environment that is called the Common Language Runtime (CLR). The UWP
extensions are called C++/CX and they produce native machine code.

7 Note

For new applications, we recommend using C++/WinRT rather than C++/CX.


C++/WinRT is a new, standard C++17 language projection for Windows Runtime
APIs. We will continue to support C++/CX and WRL, but highly recommend that
new applications use C++/WinRT. For more information, see C++/WinRT.

Two runtimes, one set of extensions


C++/CLI extends the ISO/ANSI C++ standard, and is defined under the Ecma C++/CLI
Standard. For more information, see .NET Programming with C++/CLI (Visual C++).

The C++/CX extensions are a subset of C++/CLI. Although the extension syntax is
identical in most cases, the code that is generated depends on whether you specify the
/ZW compiler option to target UWP, or the /clr option to target .NET. These switches
are set automatically when you use Visual Studio to create a project.

Data Type Keywords


The language extensions include aggregate keywords, which consist of two tokens
separated by white space. The tokens might have one meaning when they are used
separately, and another meaning when they are used together. For example, the word
"ref" is an ordinary identifier, and the word "class" is a keyword that declares a native
class. But when these words are combined to form ref class, the resulting aggregate
keyword declares an entity that is known as a runtime class.
The extensions also include context-sensitive keywords. A keyword is treated as context-
sensitive depending on the kind of statement that contains it, and its placement in that
statement. For example, the token "property" can be an identifier, or it can declare a
special kind of public class member.

The following table lists keywords in the C++ language extension.

Keyword Context Purpose Reference


sensitive

ref class No Declares a class. Classes and Structs

ref struct

value class No Declares a value class. Classes and Structs

value struct

interface class No Declares an interface. interface class

interface
struct

enum class No Declares an enum class


enumeration.
enum struct

property Yes Declares a property. property

delegate Yes Declares a delegate. delegate (C++/CLI and


C++/CX)

event Yes Declares an event. event

Override Specifiers
You can use the following keywords to qualify override behavior for derivation. Although
the new keyword is not an extension of C++, it is listed here because it can be used in
an additional context. Some specifiers are also valid for native programming. For more
information, see How to: Declare Override Specifiers in Native Compilations (C++/CLI).

Keyword Context Purpose Reference


Sensitive

abstract Yes Indicates that functions or classes are abstract. abstract


Keyword Context Purpose Reference
Sensitive

new No Indicates that a function is not an override of a new (new slot in


base class version. vtable)

override Yes Indicates that a method must be an override of a override


base-class version.

sealed Yes Prevents classes from being used as base classes. sealed

Keywords for Generics


The following keywords have been added to support generic types. For more
information, see Generics.

Keyword Context Purpose


sensitive

generic No Declares a generic type.

where Yes Specifies the constraints that are applied to a generic type
parameter.

Miscellaneous Keywords
The following keywords have been added to the C++ extensions.

Keyword Context Purpose Reference


sensitive

finally Yes Indicates default exception handlings behavior. Exception


Handling

for each, No Enumerates elements of a collection. for each, in


in

gcnew No Allocates types on the garbage-collected heap. Use ref new,


instead of new and delete . gcnew

ref new Yes Allocates a Windows Runtime type. Use instead of new ref new,
and delete . gcnew

initonly Yes Indicates that a member can only be initialized at initonly


declaration or in a static constructor. (C++/CLI)

literal Yes Creates a literal variable. literal


Keyword Context Purpose Reference
sensitive

nullptr No Indicates that a handle or pointer does not point at an nullptr


object.

Template Constructs
The following language constructs are implemented as templates, instead of as
keywords. If you specify the /ZW compiler option, they are defined in the lang
namespace. If you specify the /clr compiler option, they are defined in the cli
namespace.

Keyword Purpose Reference

array Declares an array. Arrays

interior_ptr (CLR only) Points to data in a reference type. interior_ptr


(C++/CLI)

pin_ptr (CLR only) Points to CLR reference types to temporarily suppress pin_ptr
the garbage-collection system. (C++/CLI)

safe_cast Determines and executes the optimal casting method for a safe_cast
runtime type.

typeid (CLR only) Retrieves a System.Type object that describes the given typeid
type or object.

Declarators
The following type declarators instruct the runtime to automatically manage the lifetime
and deletion of allocated objects.

Operator Purpose Reference

^ Declares a handle to an object; that is, a pointer to a Windows Handle to


Runtime or CLR object that is automatically deleted when it is no Object
longer usable. Operator (^)

% Declares a tracking reference; that is, a reference to a Windows Tracking


Runtime or CLR object that is automatically deleted when it is no Reference
longer usable. Operator
Additional Constructs and Related Topics
This section lists additional programming constructs, and topics that pertain to the CLR.

Topic Description

__identifier (C++/CLI) (Windows Runtime and CLR) Enables the use of keywords as
identifiers.

Variable Argument Lists (...) (Windows Runtime and CLR) Enables a function to take a variable
(C++/CLI) number of arguments.

.NET Framework Equivalents Lists the CLR types that are used in place of C++ integral types.
to C++ Native Types
(C++/CLI)

appdomain __declspec __declspec modifier that mandates that static and global
modifier variables exist per appdomain.

C-Style Casts with /clr Describes how C-style casts are interpreted.
(C++/CLI)

__clrcall calling convention Indicates the CLR-conformant calling convention.

__cplusplus_cli Predefined Macros

Custom Attributes Describes how to define your own CLR attributes.

Exception Handling Provides an overview of exception handling.

Explicit Overrides Demonstrates how member functions can override arbitrary


members.

Friend Assemblies (C++) Discusses how a client assembly can access all types in an
assembly component.

Boxing Demonstrates the conditions in which values types are boxed.

Compiler Support for Type Discusses how to detect characteristics of types at compile time.
Traits

managed, unmanaged Demonstrates how managed and unmanaged functions can co-
pragmas exist in the same module.

process __declspec modifier __declspec modifier that mandates that static and global
variables exist per process.

Reflection (C++/CLI) Demonstrates the CLR version of run-time type information.

String Discusses compiler conversion of string literals to String.


Topic Description

Type Forwarding (C++/CLI) Enables the movement of a type in a shipping assembly to


another assembly so that client code does not have to be
recompiled.

User-Defined Attributes Demonstrates user-defined attributes.

#using Directive Imports external assemblies.

XML Documentation Explains XML-based code documentation by using /doc (Process


Documentation Comments) (C/C++)

See also
.NET Programming with C++/CLI (Visual C++)
Native and .NET Interoperability
C++ Attributes for COM and .NET
Article • 02/07/2023

Microsoft defines a set of C++ attributes that simplify COM programming and .NET
Framework common language runtime development. When you include attributes in
your source files, the compiler works with provider DLLs to insert code or modify the
code in the generated object files. These attributes aid in the creation of .idl files,
interfaces, type libraries, and other COM elements. In the integrated development
environment (IDE), attributes are supported by the wizards and by the Properties
window.

While attributes eliminate some of the detailed coding needed to write COM objects,
you need a background in COM fundamentals to best use them.

7 Note

If you are looking for C++ standard attributes, see Attributes.

Purpose of Attributes
Attributes extend C++ in directions not currently possible without breaking the classic
structure of the language. Attributes allow providers (separate DLLs) to extend language
functionality dynamically. The primary goal of attributes is to simplify the authoring of
COM components, in addition to increasing the productivity level of the component
developer. Attributes can be applied to nearly any C++ construct, such as classes, data
members, or member functions. The following is a highlight of benefits provided by this
new technology:

Exposes a familiar and simple calling convention.

Uses inserted code, which, unlike macros, is recognized by the debugger.

Allows easy derivation from base classes without burdensome implementation


details.

Replaces the large amount of IDL code required by a COM component with a few
concise attributes.

For example, to implement a simple event sink for a generic ATL class, you could apply
the event_receiver attribute to a specific class such as CMyReceiver . The event_receiver
attribute is then compiled by the Microsoft C++ compiler, which inserts the proper code
into the object file.

C++

[event_receiver(com)]
class CMyReceiver
{
void handler1(int i) { ... }
void handler2(int i, float j) { ... }
}

You can then set up the CMyReceiver methods handler1 and handler2 to handle events
(using the intrinsic function __hook) from an event source, which you can create using
event_source.

Basic Mechanics of Attributes


There are three ways to insert attributes into your project. First, you can insert them
manually into your source code. Second, you can insert them using the property grid of
an object in your project. Finally, you can insert them using the various wizards. For
more information on using the Properties window and the various wizards, see Visual
Studio Projects - C++.

As before, when the project is built, the compiler parses each C++ source file, producing
an object file. However, when the compiler encounters an attribute, it is parsed and
syntactically verified. The compiler then dynamically calls an attribute provider to insert
code or make other modifications at compile time. The implementation of the provider
differs depending on the type of attribute. For example, ATL-related attributes are
implemented by Atlprov.dll.

The following figure demonstrates the relationship between the compiler and the
attribute provider.
7 Note

Attribute usage does not alter the contents of the source file. The only time the
generated attribute code is visible is during debugging sessions. In addition, for
each source file in the project, you can generate a text file that displays the results
of the attribute substitution. For more information on this procedure, see /Fx
(Merge Injected Code) and Debug injected code.

Like most C++ constructs, attributes have a set of characteristics that defines their
proper usage. This is referred to as the context of the attribute and is addressed in the
attribute context table for each attribute reference topic. For example, the coclass
attribute can only be applied to an existing class or structure, as opposed to the
cpp_quote attribute, which can be inserted anywhere within a C++ source file.

Building an Attributed Program


After you put Visual C++ attributes into your source code, you may want the Microsoft
C++ compiler to produce a type library and .idl file for you. The following linker options
help you build .tlb and .idl files:

/IDLOUT

/IGNOREIDL

/MIDL

/TLBOUT

Some projects contain multiple independent .idl files. These are used to produce two or
more .tlb files and optionally bind them into the resource block. This scenario is not
currently supported in Visual C++.

In addition, the Visual C++ linker will output all IDL-related attribute information to a
single MIDL file. There will be no way to generate two type libraries from a single
project.

Attribute Contexts
C++ attributes can be described using four basic fields: the target they can be applied
to (Applies To), if they are repeatable or not (Repeatable), the required presence of
other attributes (Required Attributes), and incompatibilities with other attributes
(Invalid Attributes). These fields are listed in an accompanying table in each attribute's
reference topic. Each of these fields is described below.

Applies To
This field describes the different C++ language elements that are legal targets for the
specified attribute. For instance, if an attribute specifies "class" in the Applies To field,
this indicates that the attribute can only be applied to a legal C++ class. If the attribute
is applied to a member function of a class, a syntax error would result.

For more information, see Attributes by Usage.

Repeatable
This field states whether the attribute can be repeatedly applied to the same target. The
majority of attributes are not repeatable.

Required Attributes
This field lists other attributes that need to be present (that is, applied to the same
target) for the specified attribute to function properly. It is uncommon for an attribute
to have any entries for this field.

Invalid Attributes
This field lists other attributes that are incompatible with the specified attribute. It is
uncommon for an attribute to have any entries for this field.

Debug injected code


Using attributes can greatly simplify C++ programming. For more information, see
Concepts. Some attributes are interpreted directly by the compiler. Other attributes
inject code into the program source, which the compiler then compiles. This injected
code makes programming easier by reducing the amount of code you have to write.
Sometimes, however, a bug may cause your application to fail while it is executing
injected code. When this happens, you will probably want to look at the injected code.
Visual Studio provides two ways for you to see injected code:

You can view injected code in the Disassembly window.


Using /Fx, you can create a merged source file that contains original and injected
code.

The Disassembly window shows assembly-language instructions that correspond to the


source code and the code injected by attributes. In addition, the Disassembly window
can show the source-code annotation.

To turn on Source Annotation


Right-click the Disassembly window, and choose Show Source Code from the
shortcut menu.

If you know the location of an attribute in a source window, you can use the
shortcut menu to find the injected code in the Disassembly window.

To view injected code


1. The debugger must be in break mode.

2. In a source code window, place the cursor in front of the attribute whose injected
code you want to view.

3. Right-click, and select Go To Disassembly from the shortcut menu.

If the attribute location is near the current execution point, you can select the
Disassembly window from the Debug menu.

To view the disassembly code at the current execution


point
1. The debugger must be in break mode.

2. From the Debug menu, choose Windows, and click Disassembly.

In This Section
Attribute Programming FAQ
Attributes by Group
Attributes by Usage
Attributes Alphabetical Reference
Libraries
Article • 08/03/2021

Visual Studio includes the following libraries when you install one or more of the C++
workloads. For information about installing 3rd-party libraries, see vcpkg.

Standard Libraries
C Runtime Library
C++ Standard Library
SafeInt Library
OpenMP

Libraries for Windows applications


MFC/ATL
Parallel Libraries
Data Access Libraries
Microsoft C runtime library (CRT)
reference
Article • 10/19/2022

The Microsoft runtime library provides routines for programming the Microsoft
Windows operating system. These routines automate many common programming
tasks that aren't provided by the C and C++ languages.

Sample programs are included in the individual reference articles for most routines in
the library.

In this section
Universal C runtime routines by category
Provides links to the runtime library by category.

Global variables and standard types


Provides links to the global variables and standard types provided by the runtime
library.

Global constants
Provides links to the global constants defined by the runtime library.

Global state
Describes the scope of global state in the C runtime library.

Generic-text mappings
Provides links to the generic-text mappings defined in Tchar.h.

Alphabetical function reference


Provides links to the C runtime library functions, organized alphabetically.

Function family overviews


Provides links to the C runtime library functions, organized by function family.

Language and country/region strings


Describes how to use the setlocale function to set the language and Country/Region
strings.

C runtime (CRT) and C++ Standard Library (STL) .lib files


List of .lib files that make up the C runtime libraries and their associated compiler
options and preprocessor directives.
Related sections
Debug routines
Provides links to the debug versions of the runtime library routines.

Runtime error checking


Provides links to functions that support runtime error checks.

DLLs and Visual C++ runtime library behavior


Discusses the entry point and startup code used for a DLL.

Debugging
Provides links to using the Visual Studio debugger to correct logic errors in your
application or stored procedures.
C++ Standard Library reference (STL)
Article • 08/17/2022

A C++ program can call on a large number of functions from this conforming
implementation of the C++ Standard Library. These functions perform services such as
input and output and provide efficient implementations of frequently used operations.

For more information about linking with the appropriate Visual C++ runtime .lib file,
see C runtime (CRT) and C++ Standard Library (STL) .lib files.

7 Note

Microsoft's implementation of the C++ Standard Library is often referred to as the


STL or Standard Template Library. Although C++ Standard Library is the official
name of the library as defined in ISO 14882, due to the popular use of "STL" and
"Standard Template Library" in search engines, we occasionally use those names to
make it easier to find our documentation.

From a historical perspective, "STL" originally referred to the Standard Template Library
written by Alexander Stepanov. Parts of that library were standardized in the C++
Standard Library, along with the ISO C runtime library, parts of the Boost library, and
other functionality. Sometimes "STL" is used to refer to the containers and algorithms
parts of the C++ Standard Library adapted from Stepanov's STL. In this documentation,
Standard Template Library (STL) refers to the C++ Standard Library as a whole.

In this section
C++ Standard Library overview Provides an overview of the Microsoft implementation of
the C++ Standard Library.

iostream programming Provides an overview of iostream programming.

Header files reference Provides links to reference topics about the C++ Standard Library
header files, with code examples.
SafeInt Library
Article • 08/03/2021

SafeInt is a portable library that can be used with MSVC, GCC or Clang to help prevent
integer overflows that might result when the application performs mathematical
operations. The latest version of this library is located at
https://github.com/dcleblanc/SafeInt .

In This Section
Section Description

SafeInt Class This class protects against integer overflows.

SafeInt Functions Functions that can be used without creating a SafeInt object.

SafeIntException Class A class of exceptions related to the SafeInt class.

Related Sections
Section Description

C++ Language Reference Reference and conceptual content for the C++ language.
SafeInt Class
Article • 02/17/2022

Extends the integer primitives to help prevent integer overflow and lets you compare
different types of integers.

7 Note

The latest version of the SafeInt library is located at


https://github.com/dcleblanc/SafeInt . To use the SafeInt library, clone the repo
and #include "SafeInt.hpp"

Syntax
C++

template<typename T, typename E = _SAFEINT_DEFAULT_ERROR_POLICY>


class SafeInt;

Parameters
T

The type of integer or Boolean parameter that SafeInt replaces.

An enumerated data type that defines the error handling policy.

The type of integer or Boolean parameter for the secondary operand.

rhs
[in] An input parameter that represents the value on the right side of the operator in
several stand-alone functions.

i
[in] An input parameter that represents the value on the right side of the operator in
several stand-alone functions.

bits
[in] An input parameter that represents the value on the right side of the operator in
several stand-alone functions.

Members

Public Constructors

ノ Expand table

Name Description

SafeInt::SafeInt Default constructor.

Assignment Operators

ノ Expand table

Name Syntax

= template<typename U>
SafeInt<T,E>& operator= (const U& rhs)

= SafeInt<T,E>& operator= (const T& rhs) throw()

= template<typename U>
SafeInt<T,E>& operator= (const SafeInt<U, E>& rhs)

= SafeInt<T,E>& operator= (const SafeInt<T,E>& rhs) throw()

Casting Operators

ノ Expand table

Name Syntax

bool operator bool() throw()

char operator char() const

signed char operator signed char() const

unsigned char operator unsigned char() const

__int16 operator __int16() const

unsigned __int16 operator unsigned __int16() const


Name Syntax
__int32 operator __int32() const

unsigned __int32 operator unsigned __int32() const

long operator long() const

unsigned long operator unsigned long() const

__int64 operator __int64() const

unsigned __int64 operator unsigned __int64() const

wchar_t operator wchar_t() const

Comparison Operators

ノ Expand table

Name Syntax

< template<typename U>

bool operator< (U rhs) const throw()

< bool operator< (SafeInt<T,E> rhs) const throw()

>= template<typename U>

bool operator>= (U rhs) const throw()

>= Bool operator>= (SafeInt<T,E> rhs) const throw()

> template<typename U>

bool operator> (U rhs) const throw()

> Bool operator> (SafeInt<T,E> rhs) const throw()

<= template<typename U>

bool operator<= (U rhs) const throw()

<= bool operator<= (SafeInt<T,E> rhs) const throw()

== template<typename U>

bool operator== (U rhs) const throw()

== bool operator== (bool rhs) const throw()


Name Syntax
== bool operator== (SafeInt<T,E> rhs) const throw()

!= template<typename U>

bool operator!= (U rhs) const throw()

!= bool operator!= (bool b) const throw()

!= bool operator!= (SafeInt<T,E> rhs) const throw()

Arithmetic Operators

ノ Expand table

Name Syntax

+ const SafeInt<T,E>& operator+ () const throw()

- SafeInt<T,E> operator- () const

++ SafeInt<T,E>& operator++ ()

-- SafeInt<T,E>& operator-- ()

% template<typename U>

SafeInt<T,E> operator% (U rhs) const

% SafeInt<T,E> operator% (SafeInt<T,E> rhs) const

%= template<typename U>

SafeInt<T,E>& operator%= (U rhs)

%= template<typename U>

SafeInt<T,E>& operator%= (SafeInt<U, E> rhs)

* template<typename U>

SafeInt<T,E> operator* (U rhs) const

* SafeInt<T,E> operator* (SafeInt<T,E> rhs) const

*= SafeInt<T,E>& operator*= (SafeInt<T,E> rhs)

*= template<typename U>
Name Syntax

SafeInt<T,E>& operator*= (U rhs)

*= template<typename U>

SafeInt<T,E>& operator*= (SafeInt<U, E> rhs)

/ template<typename U>

SafeInt<T,E> operator/ (U rhs) const

/ SafeInt<T,E> operator/ (SafeInt<T,E> rhs ) const

/= SafeInt<T,E>& operator/= (SafeInt<T,E> i)

/= template<typename U>

SafeInt<T,E>& operator/= (U i)

/= template<typename U>

SafeInt<T,E>& operator/= (SafeInt<U, E> i)

+ SafeInt<T,E> operator+ (SafeInt<T,E> rhs) const

+ template<typename U>

SafeInt<T,E> operator+ (U rhs) const

+= SafeInt<T,E>& operator+= (SafeInt<T,E> rhs)

+= template<typename U>

SafeInt<T,E>& operator+= (U rhs)

+= template<typename U>

SafeInt<T,E>& operator+= (SafeInt<U, E> rhs)

- template<typename U>

SafeInt<T,E> operator- (U rhs) const

- SafeInt<T,E> operator- (SafeInt<T,E> rhs) const

-= SafeInt<T,E>& operator-= (SafeInt<T,E> rhs)

-= template<typename U>

SafeInt<T,E>& operator-= (U rhs)


Name Syntax

-= template<typename U>

SafeInt<T,E>& operator-= (SafeInt<U, E> rhs)

Logical Operators

ノ Expand table

Name Syntax

! bool operator !() const throw()

~ SafeInt<T,E> operator~ () const throw()

<< template<typename U>

SafeInt<T,E> operator<< (U bits) const throw()

<< template<typename U>

SafeInt<T,E> operator<< (SafeInt<U, E> bits) const throw()

<<= template<typename U>

SafeInt<T,E>& operator<<= (U bits) throw()

<<= template<typename U>

SafeInt<T,E>& operator<<= (SafeInt<U, E> bits) throw()

>> template<typename U>

SafeInt<T,E> operator>> (U bits) const throw()

>> template<typename U>

SafeInt<T,E> operator>> (SafeInt<U, E> bits) const throw()

>>= template<typename U>

SafeInt<T,E>& operator>>= (U bits) throw()

>>= template<typename U>

SafeInt<T,E>& operator>>= (SafeInt<U, E> bits) throw()

& SafeInt<T,E> operator& (SafeInt<T,E> rhs) const throw()


Name Syntax
& template<typename U>

SafeInt<T,E> operator& (U rhs) const throw()

&= SafeInt<T,E>& operator&= (SafeInt<T,E> rhs) throw()

&= template<typename U>

SafeInt<T,E>& operator&= (U rhs) throw()

&= template<typename U>

SafeInt<T,E>& operator&= (SafeInt<U, E> rhs) throw()

^ SafeInt<T,E> operator^ (SafeInt<T,E> rhs) const throw()

^ template<typename U>

SafeInt<T,E> operator^ (U rhs) const throw()

^= SafeInt<T,E>& operator^= (SafeInt<T,E> rhs) throw()

^= template<typename U>

SafeInt<T,E>& operator^= (U rhs) throw()

^= template<typename U>

SafeInt<T,E>& operator^= (SafeInt<U, E> rhs) throw()

| SafeInt<T,E> operator| (SafeInt<T,E> rhs) const throw()

| template<typename U>

SafeInt<T,E> operator| (U rhs) const throw()

|= SafeInt<T,E>& operator|= (SafeInt<T,E> rhs) throw()

|= template<typename U>

SafeInt<T,E>& operator|= (U rhs) throw()

|= template<typename U>

SafeInt<T,E>& operator|= (SafeInt<U, E> rhs) throw()

Remarks
The SafeInt class protects against integer overflow in mathematical operations. For
example, consider adding two 8-bit integers: one has a value of 200 and the second has
a value of 100. The correct mathematical operation would be 200 + 100 = 300. However,
because of the 8-bit integer limit, the upper bit will be lost and the compiler will return
44 (300 - 28) as the result. Any operation that depends on this mathematical equation
will generate unexpected behavior.

The SafeInt class checks whether an arithmetic overflow occurs or whether the code
tries to divide by zero. In both cases, the class calls the error handler to warn the
program of the potential problem.

This class also lets you compare two different types of integers as long as they are
SafeInt objects. Typically, when you do a comparison, you must first convert the

numbers to be the same type. Casting one number to another type often requires
checks to make sure that there is no loss of data.

The Operators table in this topic lists the mathematical and comparison operators
supported by the SafeInt class. Most mathematical operators return a SafeInt object
of type T .

Comparison operations between a SafeInt and an integral type can be performed in


either direction. For example, both SafeInt<int>(x) < y and y> SafeInt<int>(x) are
valid and will return the same result.

Many binary operators don't support using two different SafeInt types. One example of
this is the & operator. SafeInt<T, E> & int is supported, but SafeInt<T, E> &
SafeInt<U, E> isn't. In the latter example, the compiler does not know what type of

parameter to return. One solution to this problem is to cast the second parameter back
to the base type. By using the same parameters, this can be done with SafeInt<T, E> &
(U)SafeInt<U, E> .

7 Note

For any bitwise operations, the two different parameters should be the same size. If
the sizes differ, the compiler will throw an ASSERT exception. The results of this
operation can't be guaranteed to be accurate. To resolve this issue, cast the smaller
parameter until it's the same size as the larger parameter.

For the shift operators, shifting more bits than exist for the template type will throw an
ASSERT exception. This will have no effect in release mode. Mixing two types of SafeInt
parameters is possible for the shift operators because the return type is the same as the
original type. The number on the right side of the operator only indicates the number of
bits to shift.

When you do a logical comparison with a SafeInt object, the comparison is strictly
arithmetic. For example, consider these expressions:

SafeInt<uint>((uint)~0) > -1

((uint)~0) > -1

The first statement resolves to true , but the second statement resolves to false . The
bitwise negation of 0 is 0xFFFFFFFF. In the second statement, the default comparison
operator compares 0xFFFFFFFF to 0xFFFFFFFF and considers them to be equal. The
comparison operator for the SafeInt class realizes that the second parameter is
negative whereas the first parameter is unsigned. Therefore, although the bit
representation is identical, the SafeInt logical operator realizes that the unsigned
integer is larger than -1.

Be careful when you use the SafeInt class together with the ?: ternary operator.
Consider the following line of code.

C++

Int x = flag ? SafeInt<unsigned int>(y) : -1;

The compiler converts it to this:

C++

Int x = flag ? SafeInt<unsigned int>(y) : SafeInt<unsigned int>(-1);

If flag is false , the compiler throws an exception instead of assigning the value of -1
to x . Therefore, to avoid this behavior, the correct code to use is the following line.

C++

Int x = flag ? (int) SafeInt<unsigned int>(y) : -1;

T and U can be assigned a Boolean type, character type, or integer type. The integer

types can be signed or unsigned and any size from 8 bits to 64 bits.

7 Note
Although the SafeInt class accepts any kind of integer, it performs more efficiently
with unsigned types.

E is the error handling mechanism that SafeInt uses. Two error handling mechanisms

are provided with the SafeInt library. The default policy is


SafeIntErrorPolicy_SafeIntException , which throws a SafeIntException Class exception

when an error occurs. The other policy is SafeIntErrorPolicy_InvalidParameter , which


stops the program if an error occurs.

There are two options to customize the error policy. The first option is to set the
parameter E when you create a SafeInt . Use this option when you want to change the
error handling policy for just one SafeInt . The other option is to define
_SAFEINT_DEFAULT_ERROR_POLICY to be your customized error-handling class before
you include the SafeInt library. Use this option when you want to change the default
error handling policy for all instances of the SafeInt class in your code.

7 Note

A customized class that handles errors from the SafeInt library should not return
control to the code that called the error handler. After the error handler is called,
the result of the SafeInt operation can't be trusted.

Inheritance Hierarchy
SafeInt

Requirements
Header: SafeInt.hpp

7 Note

The latest version of this library is located at


https://github.com/dcleblanc/SafeInt . Clone the library and include SafeInt.hpp
to use the SafeInt library. Prefer this GitHub repo to <safeint.h>. it's a modern
version of <safeint.h> that includes a small number of bug fixes, uses modern
features of C++ resulting in more efficient code, and is portable to any platform
using gcc, clang, or Intel compilers.
Example
C

#include "SafeInt.hpp" // set path to your clone of the SafeInt GitHub repo
(https://github.com/dcleblanc/SafeInt)

int main()
{
int divisor = 3;
int dividend = 6;
int result;

bool success = SafeDivide(dividend, divisor, result); // result = 2


success = SafeDivide(dividend, 0, result); // expect fail. result isn't
modified.
}

Namespace: none

SafeInt::SafeInt
Constructs a SafeInt object.

C++

SafeInt() throw

SafeInt (const T& i) throw ()

SafeInt (bool b) throw ()

template <typename U>


SafeInt (const SafeInt <U, E>& u)

I template <typename U>


SafeInt (const U& i)

Parameters
i

[in] The value for the new SafeInt object. This must be a parameter of type T or U,
depending on the constructor.

b
[in] The Boolean value for the new SafeInt object.
u

[in] A SafeInt of type U. The new SafeInt object will have the same value as u, but will
be of type T.

U The type of data stored in the SafeInt . This can be either a Boolean, character, or

integer type. If it's an integer type, it can be signed or unsigned and be between 8 and
64 bits.

Remarks
The input parameter for the constructor, i or u, must be a Boolean, character, or integer
type. If it's another type of parameter, the SafeInt class calls static_assert to indicate an
invalid input parameter.

The constructors that use the template type U automatically convert the input
parameter to the type specified by T . The SafeInt class converts the data without any
loss of data. It reports to the error handler E if it can't convert the data to type T
without data loss.

If you create a SafeInt from a Boolean parameter, you need to initialize the value
immediately. You can't construct a SafeInt using the code SafeInt<bool> sb; . This will
generate a compile error.
SafeInt Functions
Article • 08/03/2021

The SafeInt library provides several functions that you can use without creating an
instance of the SafeInt class. If you want to protect a single mathematical operation
from integer overflow, you can use these functions. If you want to protect multiple
mathematical operations, you should create SafeInt objects. It's more efficient to create
SafeInt objects than to use these functions multiple times.

These functions enable you to compare or perform mathematical operations on two


different types of parameters without having to convert them to the same type first.

Each of these functions has two template types: T and U . Each of these types can be a
Boolean, character, or integral type. Integral types can be signed or unsigned and any
size from 8 bits to 64 bits.

7 Note

The latest version of this library is located at


https://github.com/dcleblanc/SafeInt .

In This Section
Function Description

SafeAdd Adds two numbers and protects against overflow.

SafeCast Casts one type of parameter to another type.

SafeDivide Divides two numbers and protects against dividing


by zero.

SafeEquals, SafeGreaterThan, Compares two numbers. These functions enable you


SafeGreaterThanEquals, SafeLessThan, to compare two different types of numbers without
SafeLessThanEquals, SafeNotEquals changing their types.

SafeModulus Performs the modulus operation on two numbers.

SafeMultiply Multiplies two numbers together and protects


against overflow.

SafeSubtract Subtracts two numbers and protects against


overflow.
Related Sections
Section Description

SafeInt The SafeInt class.

SafeIntException The exception class specific to the SafeInt library.

SafeAdd
Adds two numbers in a way that protects against overflow.

C++

template<typename T, typename U>


inline bool SafeAdd (
T t,
U u,
T& result
) throw ();

Parameters
t
[in] The first number to add. This must be of type T.

u
[in] The second number to add. This must be of type U.

result
[out] The parameter where SafeAdd stores the result.

Return Value
true if no error occurs; false if an error occurs.

SafeCast
Casts one type of number to another type.

C++
template<typename T, typename U>
inline bool SafeCast (
const T From,
U& To
);

Parameters
From
[in] The source number to convert. This must be of type T .

To
[out] A reference to the new number type. This must be of type U .

Return Value
true if no error occurs; false if an error occurs.

SafeDivide
Divides two numbers in a way that protects against dividing by zero.

C++

template<typename T, typename U>


inline bool SafeDivide (
T t,
U u,
T& result
) throw ();

Parameters
t
[in] The dividend. This must be of type T.

u
[in] The divisor. This must be of type U.

result
[out] The parameter where SafeDivide stores the result.
Return Value
true if no error occurs; false if an error occurs.

SafeEquals
Compares two numbers to determine whether they're equal.

C++

template<typename T, typename U>


inline bool SafeEquals (
const T t,
const U u
) throw ();

Parameters
t
[in] The first number to compare. This must be of type T.

u
[in] The second number to compare. This must be of type U.

Return Value
true if t and u are equal; otherwise false .

Remarks
The method enhances == because SafeEquals enables you to compare two different
types of numbers.

SafeGreaterThan
Compares two numbers.

C++

template<typename T, typename U>


inline bool SafeGreaterThan (
const T t,
const U u
) throw ();

Parameters
t
[in] The first number to compare. This must be of type T .

u
[in] The second number to compare. This must be of type U .

Return Value
true if t is greater than u; otherwise false .

Remarks
SafeGreaterThan extends the regular comparison operator by enabling you to compare
two different types of numbers.

SafeGreaterThanEquals
Compares two numbers.

C++

template <typename T, typename U>


inline bool SafeGreaterThanEquals (
const T t,
const U u
) throw ();

Parameters
t
[in] The first number to compare. This must be of type T .

u
[in] The second number to compare. This must be of type U .

Return Value
true if t is greater than or equal to u; otherwise false .

Remarks
SafeGreaterThanEquals enhances the standard comparison operator because it enables

you to compare two different types of numbers.

SafeLessThan
Determines whether one number is less than another.

C++

template<typename T, typename U>


inline bool SafeLessThan (
const T t,
const U u
) throw ();

Parameters
t
[in] The first number. This must be of type T .

u
[in] The second number. This must be of type U .

Return Value
true if t is less than u; otherwise false .

Remarks
This method enhances the standard comparison operator because SafeLessThan
enables you to compare two different types of number.

SafeLessThanEquals
Compares two numbers.

C++
template <typename T, typename U>
inline bool SafeLessThanEquals (
const T t,
const U u
) throw ();

Parameters
t
[in] The first number to compare. This must be of type T .

u
[in] The second number to compare. This must be of type U .

Return Value
true if t is less than or equal to u; otherwise false .

Remarks
SafeLessThanEquals extends the regular comparison operator by enabling you to

compare two different types of numbers.

SafeModulus
Performs the modulus operation on two numbers.

C++

template<typename T, typename U>


inline bool SafeModulus (
const T t,
const U u,
T& result
) throw ();

Parameters
t
[in] The divisor. This must be of type T .
u
[in] The dividend. This must be of type U .

result
[out] The parameter where SafeModulus stores the result.

Return Value
true if no error occurs; false if an error occurs.

SafeMultiply
Multiplies two numbers together in a way that protects against overflow.

C++

template<typename T, typename U>


inline bool SafeMultiply (
T t,
U u,
T& result
) throw ();

Parameters
t
[in] The first number to multiply. This must be of type T .

u
[in] The second number to multiply. This must be of type U .

result
[out] The parameter where SafeMultiply stores the result.

Return Value
true if no error occurs; false if an error occurs.

SafeNotEquals
Determines if two numbers aren't equal.
C++

template<typename T, typename U>


inline bool SafeNotEquals (
const T t,
const U u
) throw ();

Parameters
t
[in] The first number to compare. This must be of type T .

u
[in] The second number to compare. This must be of type U .

Return Value
true if t and u aren't equal; otherwise false .

Remarks
The method enhances != because SafeNotEquals enables you to compare two different
types of numbers.

SafeSubtract
Subtracts two numbers in a way that protects against overflow.

C++

template<typename T, typename U>


inline bool SafeSubtract (
T t,
U u,
T& result
) throw ();

Parameters
t
[in] The first number in the subtraction. This must be of type T .
u
[in] The number to subtract from t. This must be of type U .

result
[out] The parameter where SafeSubtract stores the result.

Return Value
true if no error occurs; false if an error occurs.
SafeIntException Class
Article • 08/03/2021

The SafeInt class uses SafeIntException to identify why a mathematical operation


cannot be completed.

7 Note

The latest version of this library is located at


https://github.com/dcleblanc/SafeInt .

Syntax
C++

class SafeIntException;

Members

Public Constructors

Name Description

SafeIntException::SafeIntException Creates a SafeIntException object.

Remarks
The SafeInt class is the only class that uses the SafeIntException class.

Inheritance Hierarchy
SafeIntException

Requirements
Header: safeint.h
Namespace: msl::utilities

SafeIntException::SafeIntException
Creates a SafeIntException object.

C++

SafeIntException();

SafeIntException(
SafeIntError code
);

Parameters
code
[in] An enumerated data value that describes the error that occurred.

Remarks
The possible values for code are defined in the file Safeint.h. For convenience, the
possible values are also listed here.

SafeIntNoError
SafeIntArithmeticOverflow

SafeIntDivideByZero
MFC and ATL
Article • 09/21/2021

The Microsoft Foundation Classes (MFC) provide a C++ object-oriented wrapper over
Win32 for rapid development of native desktop applications. The Active Template
Library (ATL) is a wrapper library that simplifies COM development and is used
extensively for creating ActiveX controls.

You can create MFC or ATL programs with Visual Studio Community Edition or higher.
The Express editions do not support MFC or ATL.

In Visual Studio 2015, Visual C++ is an optional component, and MFC and ATL
components are optional sub-components under Visual C++. If you do not select these
components when you first install Visual Studio, you will be prompted to install them
the first time you attempt to create or open an MFC or ATL project.

In Visual Studio 2017 and later, MFC and ATL are optional sub-components under the
Desktop development with C++ workload in the Visual Studio Installer program. You
can install ATL support without MFC, or combined MFC and ATL support (MFC depends
on ATL). For more information about workloads and components, see Install Visual
Studio.

Related Articles
Title Description

MFC Desktop Microsoft Foundation Classes provide a thin object-oriented wrapper over
Applications Win32 to enable rapid development of GUI applications in C++.

ATL COM ATL provides class templates and other use constructs to simplify creation of
Desktop COM objects in C++.
Components

ATL/MFC Shared References for CStringT Class and other classes that are shared by MFC and
Classes ATL.

Working with The resource editor lets you edit UI resources such as strings, images, and
Resource Files dialog boxes.

C++ in Visual Parent topic for all C++ documentation.


Studio
Parallel Programming in Visual C++
Article • 09/21/2021

Visual C++ provides the following technologies to help you create multi-threaded and
parallel programs that take advantage of multiple cores and use the GPU for general
purpose programming.

Related Articles
Title Description

Auto-Parallelization and Compiler optimizations that speed up code.


Auto-Vectorization

Concurrency Runtime Classes that simplify the writing of programs that use data
parallelism or task parallelism.

C++ AMP (C++ Accelerated Classes that enable the use of modern graphics processors for
Massive Parallelism) general purpose programming.

Multithreading Support for Older technologies that may be useful in older applications. For
Older Code (Visual C++) new apps, use the Concurrency Runtime or C++ AMP.

OpenMP The Microsoft implementation of the OpenMP API.

C++ in Visual Studio This section of the documentation contains information about
most of the features of Visual C++.
Data Access in Visual C++
Article • 08/03/2021

Virtually all database products, SQL and NoSQL, provide an interface for native C++
applications. The industry standard interface is ODBC which is supported by all major
SQL database products and many NoSQL products. For non-Microsoft products, consult
the vendor for more information. Third-party libraries with various license terms are also
available.

Since 2011 Microsoft has aligned on ODBC as the standard for native applications to
connecting to Microsoft SQL Server databases, both on-premises and in the cloud. For
more information, see Data Access Programming (MFC-ATL). C++/CLI libraries can use
either the native ODBC drivers or ADO.NET. For more information, see Data Access
Using ADO.NET (C++/CLI) and Accessing data in Visual Studio.

In This Section
Data Access Programming (MFC/ATL)
Describes legacy data access programming with Visual C++, where the preferred way is
to use one of the class libraries such as the Active Template Class Library (ATL) or
Microsoft Foundation Class (MFC) Library, which simplify working with the database
APIs.

Open Database Connectivity (ODBC)


The Microsoft Foundation Classes (MFC) library supplies classes for programming with
Open Database Connectivity (ODBC).

OLE DB Programming
A mostly legacy interface which is still required in some scenarios, specifically when you
are programming against linked servers.

Related Topics
Connect to SQL Database using C and C++
Connect to Azure SQL Database from C or C++ applications.

Microsoft Azure Storage Client Library for C++


Azure Storage is a cloud storage solution for modern applications that rely on durability,
availability, and scalability to meet the needs of their customers. Connect to Azure
Storage from C++ by using the Azure Storage Client Library for C++.
ODBC Driver for SQL Server
The latest ODBC driver provides robust data access to Microsoft SQL Server and
Microsoft Azure SQL Database for C/C++ based applications. Provides support for
features including always encrypted, Azure Active Directory, and AlwaysOn Availability
Groups. Also available for MacOS and Linux.

OLE DB Driver for SQL Server


The latest OLE DB driver is a stand-alone data access application programming interface
(API) that supports Microsoft SQL Server and Microsoft Azure SQL Database.

Microsoft Azure C and C++ Developer Center


Azure makes it easy to build C++ applications with increased flexibility, scalability and
reliability using tools you love.

How to use Blob Storage from C++


Azure Blob storage is a service that stores unstructured data in the cloud as
objects/blobs. Blob storage can store any type of text or binary data, such as a
document, media file, or application installer. Blob storage is also referred to as object
storage.

ODBC Programmer's Reference


The ODBC interface is designed for use with the C programming language. Use of the
ODBC interface spans three areas: SQL statements, ODBC function calls, and C
programming.

See also
C++ in Visual Studio

You might also like