Download as pdf or txt
Download as pdf or txt
You are on page 1of 361

Contents

Microsoft C/C++ in Visual Studio


C++ in Visual Studio
Overview of C++ development in Visual Studio
What's new for C++ in Visual Studio 2019
What's new for C++ in Visual Studio 2017
What's new for Microsoft C++ docs
C++ conformance improvements in Visual Studio 2019
C++ conformance improvements in Visual Studio 2017
Microsoft C/C++ language conformance
Supported target platforms
C++ Tools and Features in Visual Studio Editions
Install C11 and C17 support in Visual Studio
Samples
Help and community
How to report a problem with the Visual C++ toolset
Visual Studio C++ Tutorials
Install C++ support in Visual Studio
Create and edit a C++ console app project
Build and run a C++ console app project
Create a console calculator in C++
Create a UWP app
Create a Windows Desktop application
Create a DirectX game
Projects and build systems
Read and write code in Visual Studio
Windows desktop development
UWP development
Game development
Linux development
Cross-platform mobile development
.NET development with C++/CLI
Cloud and Web programming
Port and upgrade C++ code
Security best practices for C++
Security best practices for C++
Run as a member of the users group
How User Account Control (UAC) affects your application
C++ developer guidance for speculative execution side channels
Reference
C/C++ language and standard libraries
Languages reference
Languages
C language reference
C++ language reference
C/C++ preprocessor reference
Compiler intrinsics and assembly language
Compiler intrinsics
ARM Assembler reference
Inline assembly in MSVC
Microsoft Macro Assembler (MASM) reference
Component extensions for .NET and UWP
C++ Attributes for COM and .NET
Libraries reference
Libraries
C Run-time library (CRT) reference
C++ Standard Library reference
SafeInt library
SafeInt library
SafeInt Class
SafeInt Functions
SafeIntException Class
MFC/ATL
Parallel libraries
Data access libraries
C and C++ in Visual Studio
9/21/2021 • 6 minutes to read • Edit Online

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.

NOTE
This developer documentation applies to Visual Studio 2019. 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.

NOTE
This developer documentation applies to Visual Studio 2017. 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.

NOTE
This developer documentation applies to Visual Studio 2015. 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 Universal Windows
Platform (UWP) apps, native Windows desktop and server applications, cross-platform libraries and apps that
run on Windows, Linux, Android, and iOS, as well as managed apps and libraries that use the .NET Framework.
You can use MSVC to write anything from simple console apps to the most sophisticated and complex apps for
Windows desktop, from device drivers and operating system components to cross-platform games for mobile
devices, and from the smallest IoT devices to multi-server high performance computing in the Azure cloud.
Visual Studio 2015, 2017 and 2019 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 and Conformance History


What's New for C++ in Visual Studio
Find out what's new in Visual Studio.
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 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 to take advantage of greater
compiler conformance to the C++ standard as well as 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++
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.

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 applications in C++


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++.
Desktop applications (C++)
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.
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, and 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.

Languages reference
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 language reference
The reference guide to the Microsoft implementation of the C 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++ Libraries 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


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.

Feedback and community


Microsoft Docs Q&A
Microsoft Docs 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.
Overview of C++ development in Visual Studio
7/28/2021 • 5 minutes to read • Edit Online

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 Visual Studio 2017
and Azure Repos Git. For information about Git integration with GitHub, see GitHub Extension for Visual Studio.

Obtain libraries
Use the vcpkg package manager to obtain and install third-party libraries. Over 900 open-source libraries 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 Desktop Applications.

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
What's new for C++ in Visual Studio
9/21/2021 • 27 minutes to read • Edit Online

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 information about what's new in the C++ docs, see Microsoft C++ docs: What's new.

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.
link performance improved by multi-threading PDB creation. Several large applications and
/DEBUG:FULL
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 suppor t 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 suppor t 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 suppor t: 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.
Suppor t 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 ser vices 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 Proper ties > 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 for online docs to learn more 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 at Microsoft Docs 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 10 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
9/21/2021 • 28 minutes to read • Edit Online

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. 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.
Vi su a l St u d i o 2 0 1 7 v e r si o n 1 5 .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
Vi su a l St u d i o 2 0 1 7 v e r si o n 1 5 .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.
Vi su a l St u d i o 2 0 1 7 v e r si o n 1 5 .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.
Vi su a l St u d i o 2 0 1 7 v e r si o n 1 5 .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) has been
removed. Your code should be updated to use co_yield instead. For more information, see yield keyword
to become co_yield in VS 2017.
Vi su a l St u d i o 2 0 1 7 v e r si o n 1 5 .3

Additional improvements to diagnostics in the compiler. For more information, see Diagnostic Improvements in
Visual Studio 2017 15.3.0.
Vi su a l St u d i o 2 0 1 7 v e r si o n 1 5 .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.
Vi su a l St u d i o 2 0 1 7 v e r si o n 1 5 .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
Vi su a l St u d i o 2 0 1 7 R T M (v e r si o n 1 5 .0 )

Minor basic_string _ITERATOR_DEBUG_LEVEL != 0 diagnostics improvements. When an IDL check gets tripped
in string machinery, it will now report the specific behavior that caused the trip. For example, instead of
"string iterator not dereferencable" you'll 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.
Vi su a l St u d i o 2 0 1 7 v e r si o n 1 5 .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 non-integral 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 will now enforce 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 .
Vi su a l St u d i o 2 0 1 7 v e r si o n 1 5 .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 have been 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.


Vi su a l St u d i o 2 0 1 7 v e r si o n 1 5 .3

Several additional 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 has been 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 has been
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 has been kept for binary
compatibility. We'll remove it in the next binary-incompatible version of the standard library.
Vi su a l St u d i o 2 0 1 7 v e r si o n 1 5 .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

Vi su a l St u d i o 2 0 1 7 v e r si o n 1 5 .6

<memory_resource>
Library Fundamentals V1
Deleting polymorphic_allocator assignment
Improving class template argument deduction
Vi su a l St u d i o 2 0 1 7 v e r si o n 1 5 .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 has been 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.
Vi su a l St u d i o 2 0 1 7 v e r si o n 1 5 .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.
Vi su a l St u d i o 2 0 1 7 v e r si o n 1 5 .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 will now dispatch 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
Vi su a l St u d i o 2 0 1 7 v e r si o n 1 5 .5

The CPPRestSDK, a cross-platform web API for C++, has been updated to version 2.9.0. For more information,
see CppRestSDK 2.9.0 is available on GitHub.
ATL
Vi su a l St u d i o 2 0 1 7 v e r si o n 1 5 .5
Yet another set of name-lookup conformance fixes
Existing move constructors and move assignment operators are now properly marked as non-throwing
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 will now be faster, and all later
activations of this solution configuration will be almost instantaneous.
Vi su a l St u d i o 2 0 1 7 v e r si o n 1 5 .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.
Vi su a l St u d i o 2 0 1 7 v e r si o n 1 5 .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:

F EAT URE P ERF O RM A N C E IM P RO VEM EN T

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 has 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 will be 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 will launch 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 has been moved from experimental to advanced, and is now
enabled by default. The editor features Expand Scopes and Expand Precedence have also been 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.
Vi su a l St u d i o 2 0 1 7 v e r si o n 1 5 .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 much 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.
Vi su a l St u d i o 2 0 1 7 v e r si o n 1 5 .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've also
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.

Vi su a l St u d i o 2 0 1 7 v e r si o n 1 5 .3

Support added for the CMake Ninja generator.


Vi su a l St u d i o 2 0 1 7 v e r si o n 1 5 .4

Support added for importing existing CMake caches.


Vi su a l St u d i o 2 0 1 7 v e r si o n 1 5 .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 have
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 will stop responding.
Vi su a l St u d i o 2 0 1 7 v e r si o n 1 5 .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.
Vi su a l St u d i o 2 0 1 7 v e r si o n 1 5 .2

Improvements have been made in cross-platform code sharing and type visualization. For more information,
see Linux C++ improvements for cross-platform code sharing and type visualization.
Vi su a l St u d i o 2 0 1 7 v e r si o n 1 5 .5

The Linux workload has 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.
Vi su a l St u d i o 2 0 1 7 v e r si o n 1 5 .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.
Vi su a l St u d i o 2 0 1 7 v e r si o n 1 5 .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.
Vi su a l St u d i o 2 0 1 7 v e r si o n 1 5 .3

Support added for rules related to resource management.


Vi su a l St u d i o 2 0 1 7 v e r si o n 1 5 .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 may find in 15.3 are no longer available in 15.5. These warnings were
replaced with more specific checks.
Vi su a l St u d i o 2 0 1 7 v e r si o n 1 5 .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
Vi su a l St u d i o 2 0 1 7 v e r si o n 1 5 .7

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

Unit testing in Visual Studio 2017


Vi su a l St u d i o 2 0 1 7 v e r si o n 1 5 .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++.
Vi su a l St u d i o 2 0 1 7 v e r si o n 1 5 .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.
Vi su a l St u d i o 2 0 1 7 v e r si o n 1 5 .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 Ver tex and Geometr y 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 Histor y: 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 Histor y 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 may 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.
Memor y Statistics: View how much memory the driver allocates for the resources you create in the
frame. This window is available via View > Memor y 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. For more details,
watch the GoingNative 25: Visual Studio Graphics Frame Analysis video.
GPU Usage Improvements: Open traces can be taken via the Visual Studio GPU Usage profiler with
either GPU View 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 GPU
View, at the bottom right of the session overview.

Traces you open in GPU View via this link support synchronized VS and GPU View timeline zooming and
panning. A checkbox in VS controls whether synchronization is enabled or not.
Microsoft C++ docs: What's new for June 2021
9/21/2021 • 14 minutes to read • Edit Online

This article lists major changes to the Microsoft C++ docs through June 2021.
See what's new history for info about what was new in previous months.
See What's new for C++ in Visual Studio for info about what's new in Visual Studio.
See C++ conformance improvements in Visual Studio for the latest C and C++ conformance status.

Build insights
New ar ticles
HeaderUnit class
Module class
PrecompiledHeader class
TRANSLATION_UNIT_TYPE enum
TRANSLATION_UNIT_TYPE_DATA enum
TranslationUnitType class
Updated ar ticles
C++ Build Insights SDK: event table - add new C++ Build Insights events
Get started with C++ Build Insights - add new C++ Build Insights events

C language
Updated ar ticles
_Static_assert keyword and static_assert macro (C11) - update the SDK to use
Alignment (C11) - update the SDK to use
Generic selection (C11) - update the SDK to use

C runtime library
Updated ar ticles
In addition to the changes below, many articles were updated to prevent the machine translation of code
elements.
_cprintf_p, _cprintf_p_l, _cwprintf_p, _cwprintf_p_l - rounding behavior change
printf()
_cprintf_s, _cprintf_s_l, _cwprintf_s, _cwprintf_s_l -printf() rounding behavior change
_cprintf, _cprintf_l, _cwprintf, _cwprintf_l - printf() rounding behavior change
_fprintf_p, _fprintf_p_l, _fwprintf_p, _fwprintf_p_l - printf() rounding behavior change
_get_printf_count_output - printf() rounding behavior change
_printf_p, _printf_p_l, _wprintf_p, _wprintf_p_l - printf() rounding behavior change
_scprintf_p, _scprintf_p_l, _scwprintf_p, _scwprintf_p_l - printf() rounding behavior change
_scprintf, _scprintf_l, _scwprintf, _scwprintf_l - printf() rounding behavior change
_vcprintf_p, _vcprintf_p_l, _vcwprintf_p, _vcwprintf_p_l - printf() rounding behavior change
_vcprintf_s, _vcprintf_s_l, _vcwprintf_s, _vcwprintf_s_l - rounding behavior change
printf()
_vscprintf, _vscprintf_l, _vscwprintf, _vscwprintf_l - printf() rounding behavior change
_vsprintf_p, _vsprintf_p_l, _vswprintf_p, _vswprintf_p_l - printf() rounding behavior change
_snprintf_s , _snprintf_s_l , _snwprintf_s , _snwprintf_s_l - printf() rounding behavior change
errno constants - improve readability
fprintf , _fprintf_l , fwprintf , _fwprintf_l - printf() rounding behavior change
freopen_s , _wfreopen_s - new C11 flags
freopen , _wfreopen - added C11 flags
pow , powf , powl - note change to pow(T,int) starting in VS 2015 update 1
printf_s , _printf_s_l , wprintf_s , _wprintf_s_l - printf() rounding behavior change
setlocale , _wsetlocale - clarified UTF-8 string mode
sprintf , _sprintf_l , swprintf , _swprintf_l , __swprintf_l - printf() rounding behavior change
cprintf - printf() rounding behavior change
fprintf_s, _fprintf_s_l, fwprintf_s, _fwprintf_s_l - printf() rounding behavior change
sprintf_s, _sprintf_s_l, swprintf_s, _swprintf_s_l - printf() rounding behavior change
strcpy_s, wcscpy_s, _mbscpy_s, _mbscpy_s_l - fixed code examples
strncat_s, _strncat_s_l, wcsncat_s, _wcsncat_s_l, _mbsncat_s, _mbsncat_s_l - printf() rounding behavior
change
Type-generic math - updated the SDK version to use
vprintf, _vprintf_l, vwprintf, _vwprintf_l - printf() rounding behavior change
vsprintf_s, _vsprintf_s_l, vswprintf_s, _vswprintf_s_l - printf() rounding behavior change

C++ in Visual Studio


Updated ar ticles
_variant_t::operator= - add remarks for operator= and make the article easier to read.
Abstract classes (C++) - add Microsoft-specific extension information for inline pure virtual destructor
Attributes in C++ - add missing errors and warnings: C7000-C7999, C4834
char, wchar_t, char8_t, char16_t, char32_t - clarified whether char is signed or unsigned

C++ porting and upgrade guide


Updated ar ticles
Introduction to Microsoft C++ for UNIX Users - Visual Studio 16.10 updates to C17 conformance
Visual C++ What's New 2003 through 2015 - note change to pow(T,int) starting in VS 2015 update 1

C/C++ compiler and tools errors and warnings


New ar ticles
Command-line error D8048
Compiler Error C7510
Compiler Error C7536
Compiler errors C7000 through C7499
Compiler errors C7500 through C7999
Compiler Warning (error) C4597
Compiler warning (level 1) C4834
Compiler Warning (level 1) C5050
Compiler warning (level 3) C4698
Compiler Warning (level 3) C4768
Compiler Warning (level 4) C4841
Compiler Warning (level 4) C4843
Compiler warning C5037
Fatal Error C1090
Updated ar ticles
Compiler Error C2139 - added some version 2017 diagnostics
Compiler Error C2201 - added some version 2017 diagnostics
Compiler Error C2276 - update C2276
Compiler Error C2668 - added some version 2017 diagnostics
Compiler Error C2855 - add remarks about how to resolve this error
Compiler errors C2000 - C3999, C7000 - C7999 - add missing errors and warnings: C7000-C7999, C4834
Compiler errors C7500 through C7999 - added some version 2017 diagnostics; add error C7510; add
missing errors and warnings: C7000-C7999, C4834
Compiler Warning (level 1) C4179 - added some version 2017 diagnostics
Compiler Warning (level 1) C5208 and Error C7626 - add missing errors and warnings: C7000-C7999,
C4834
Compiler Warning (level 4) C4189 - added some version 2017 diagnostics
Compiler Warning C5038 - added some version 2017 diagnostics
Compiler warnings by compiler version - update Visual Studio 16.10 conformance improvements and new
warnings; Add new 16.10 warnings, version info; update version strings for Visual Studio 16.8, 16.9, and
16.10
Compiler warnings C4400 Through C4599 - added some Visual Studio version 2017 diagnostics
Compiler warnings C4800 through C5999 - update Visual Studio 16.10 conformance improvements and
new warnings; add new 16.10 warnings, version info; added some version 2017 diagnostics; add missing
errors and warnings: C7000 - C7999, C4834
Vectorizer and parallelizer messages - add vectorizer failure reason 505; add 1204 reason code

C/C++ compiler intrinsics and assembly language


Updated ar ticles
Microsoft Macro Assembler BNF Grammar - cleanup formatting and machine translation issues

C/C++ in Visual Studio overview


New ar ticles
C++ Conformance improvements, behavior changes, and bug fixes in Visual Studio 2017
Microsoft C++ docs: What's new for Visual Studio 16.8
What's new for C++ in Visual Studio 2017
Updated ar ticles
C++ Conformance improvements, behavior changes, and bug fixes in Visual Studio 2017 - added version
2017 diagnostics
C++ Conformance improvements, behavior changes, and bug fixes in Visual Studio 2019 - Visual Studio
16.10 updates to C17 conformance; update 16.10 conformance improvements and new warnings; add error
C7510; add missing errors and warnings: C7000 - C7999, C4834; update conformance docs for 16.9
C++ in Visual Studio - Visual Studio 16.10 updates to C17 conformance
Install C11 and C17 support in Visual Studio - Visual Studio 16.10 updates to C17 conformance
Microsoft C/C++ language conformance by Visual Studio version - Visual Studio 16.10 updates to C17
conformance; update conformance table for Visual Studio 16.10 and Visual Studio 16.9
Microsoft C++ docs: What's new for Visual Studio 16.8 - Visual Studio 16.10 updates to C17 conformance
What's new for C++ in Visual Studio 2017 - Visual Studio 16.10 updates to C17 conformance; update Visual
Studio 16.9 release conformance docs

C/C++ preprocessor reference


Updated ar ticles
Compiler warnings that are off by default - update Visual Studio 16.10 conformance improvements and new
warnings; added some version 2017 diagnostics
Predefined macros - add new Visual Studio 16.10 warnings, version info; update version strings for Visual
Studio 16.8, 16.9, and 16.10

C/C++ projects and build systems


New ar ticles
/external (External headers diagnostics)
/headerName (Build a header unit from the specified header)
/sourceDependencies:directives (List module and header unit dependencies)
CMakePresets.json and CMakeUserPresets.json Microsoft vendor maps
Configure and build with CMake Presets in Visual Studio
HeaderUnit class
Module class
PrecompiledHeader class
TRANSLATION_UNIT_TYPE enum
TRANSLATION_UNIT_TYPE_DATA enum
TranslationUnitType class
Walkthrough: Build and import header units in Microsoft Visual C++
Walkthrough: Import STL libraries as header units
Updated ar ticles
/experimental:module (Enable module support) - new content for header-units
/Qspectre - update for VS 2019
/Y (precompiled headers) - new content for header-units
/analyze (Code analysis) - update with up-to-date options list, add more information, and restructure for
better organization of related options
/await (Enable coroutine support) - add /await:strict for Visual Studio 16.10
/clr (Common Language Runtime Compilation) - include version for support of /clr:netcore option
/exportHeader (Create header units) - add new content related to header-units
/external (External headers diagnostics) - /external not experimental in Visual Studio 16.10
/F (Set Stack Size) - update for VS 2019
/FC (Full path of source code file in diagnostics) - Classify behavior by version.
/GL (Whole program optimization) - fix loc issue in /GL docs
/headerUnit (Use header unit IFC) - new content for header-units
/INTEGRITYCHECK (Require signature check) - updated signing guidance for integritycheck binaries
/openmp (Enable OpenMP Support) - add /openmp:llvm compiler switch docs
/reference (Use named module IFC) - new content for header-units
/sourceDependencies (List all source-level dependencies) - new content for header-units
/std (Specify Language Standard Version) - Visual Studio 16.10 updates to C17 conformance
/translateInclude (Translate include directives into import directives) - new content for header-units
Advanced Property Page - add Windows Desktop Compatible property for Visual Studio 16.10; Add LLVM
toolset version option for Visual Studio 16.9
ARM Exception Handling - fix ComputeXdataSize samples for ARM/ARM64
ARM64 exception handling - fix ComputeXdataSize samples for ARM/ARM64
C++ Build Insights SDK: event table - add New C++ Build Insights Events to documentation
Clang/LLVM support in Visual Studio projects - add LLVM toolset version option for Visual Studio 16.9;
update clang-support-msbuild.md
CMake projects in Visual Studio - add advanced details about using CMake file-api
Compiler options listed alphabetically - new content for header-units
Compiler options listed by category - new content for header-units
Configure and build with CMake Presets in Visual Studio - improve readability
General Property Page (Project) - add Windows Desktop Compatible property for Visual Studio 16.10
Get started with C++ Build Insights - add New C++ Build Insights Events to documentation
How to: Modify the Target Framework and Platform Toolset - improve readability
Open Folder support for C++ build systems in Visual Studio - fix CppProperties.json MinGW-w64 contents
Unicode support in the compiler and linker - add info about how to save using a different encoding
Use the Microsoft C++ toolset from the command line - updated for VS 2019
Walkthrough: Compile a C program on the command line - Visual Studio 16.10 updates to C17 conformance
Walkthrough: Compiling a Native C++ Program on the Command Line - clarified notepad behavior when
opening source file

C++ Standard Library (STL) reference


New ar ticles
<ranges>
day class
month_day_last class
month_day class
month_weekday_last class
month_weekday class
year_month class

Updated ar ticles
bitset class - improve readability
vector class - fix typo in code sample

Code quality
New ar ticles
C6389: MARK_INTERNAL_OR_MISSING_COMMON_DECL
Updated ar ticles
C6031 - add note about ignoring a function's return value
C26432 DEFINE_OR_DELETE_SPECIAL_OPS - update code examples
C26497 USE_CONSTEXPR_FOR_FUNCTION - add note about when warning won't be issued

Linux with C++ in Visual Studio


Updated ar ticles
Connect to your target Linux system in Visual Studio - add section about host key verification
ConnectionManager reference - add note about host key fingerprint flags added in Visual Studio 16.10.

Overview of Windows programming in C++


Updated ar ticles
Determining Which DLLs to Redistribute - updated for Visual Studio 2019

Parallel programming in C++ in Visual Studio


Updated ar ticles
C++ AMP Overview - add note about C++ AMP library deprecation
Walkthrough: Debugging a C++ AMP application - fixed code sample

Community contributors
The following people contributed to the C++, C, and Assembler docs during this period. Thank you! See
Microsoft Docs contributor guide overview if you'd like to learn how to contribute.
0xbadfca11 (1)
bclehmann - Benjamin Lehmann (1)
Brian-Taylor8 (1)
cartwrightluke (2)
ccawley2011 - Cameron Cawley (1)
EddieBreeveld - Edward Breeveld (1)
FrankAtHexagon - Frank Edwards (1)
fsb4000 - Igor Zhukov (1)
Jaiganeshkumaran - Jaiganesh Kumaran (2)
jayvient - Jayvien (1)
KishkinJ10 (1)
kokosxD - kokos (1)
langemol - Jacco Mol (1)
MUzairS15 (1)
nadavsu - Nadav (1)
NegiAkash890 - Akash Negi (1)
pjessesco - Jino Park (1)
pramodkirchki (1)
Radfordhound - Graham Scott (1)
sapant-msft (1)
sebgod - Sebastian Godelet (1)
seedkar1 (1)
ShamanCoder (1)
sheila-stewart (1)
softmac (1)
Thieum - Matthieu Penant (2)
tjs137 (1)
urmyfaith - zx (1)
ValZapod - Valerii Zapodovnikov (1)
westinn - Nicolas Westin (1)

What's new history


The following section provides the previous months of what's new in the Visual Studio docs.
February 2021
C language
New ar ticles
_Noreturn keyword and noreturn macro (C11)
_Static_assert keyword and static_assert macro (C11)

Updated ar ticles
C Assignment Operators - lexical grammar update for C17
C enumeration declarations - fixed lexical grammar
C Keywords - lexical grammar update for C17
C Lexical grammar - lexical grammar update for C17
Parsing C Command-Line Arguments - Document exceptions to the rules for parsing C arguments
Summary of C statements - updated for __leave , __try keywords
Summary of Declarations - lexical grammar update for C17
Summary of Expressions - lexical grammar update for C17
Type Qualifiers - added restrict
C runtime library
New ar ticles
Type-generic math
Updated ar ticles
_cwait - fixed code example
assert Macro, _assert, _wassert - Clarified assert behavior
qsort - added note about stability
realloc - added C99 conformance notes
round, roundf, roundl - Clarified rounding code example
setlocale, _wsetlocale - added C Runtime UTF-8 support info
vsnprintf_s, _vsnprintf_s, _vsnprintf_s_l, _vsnwprintf_s, _vsnwprintf_s_l - Clarified return values
Compatibility - added C99 conformance notes
CRT Library Features - added C99 conformance notes
Function family overview - added operator new and delete
C/C++ preprocessor reference
Updated ar ticles
MSVC new preprocessor overview - updated preprocessor content
Predefined macros - updated to Visual Studio 16.8 release notes, C11/C17 /std support and SDK install
docs
Code quality
New ar ticles
C33001 - VC Code Analysis - add for new rules in Visual Studio 16.8
C33004 - VC Code Analysis - add for new rules in Visual Studio 16.8
C33005 - VC Code Analysis - add for new rules in Visual Studio 16.8
C33010 - VC Code Analysis - add for new rules in Visual Studio 16.8
C33011 - VC Code Analysis - add for new rules in Visual Studio 16.8
C33020 - VC Code Analysis - add for new rules in Visual Studio 16.8
C33022 - VC Code Analysis - add for new rules in Visual Studio 16.8
Updated ar ticles
C6262 - address cpp-docs.zh-tw issue 20
C26401 DONT_DELETE_NON_OWNER - added example and Core Guidelines link to C26401
C26402DONT_HEAP_ALLOCATE_MOVABLE_RESULT - added example for C26402
C26408 NO_MALLOC_FREE - added example and Core Guidelines link to C26408
C26409 NO_NEW_DELETE - added example for C26409
C26432 DEFINE_OR_DELETE_SPECIAL_OPS - added example for C26432
C26434 DONT_HIDE_METHODS - added example for C26434
C26436 NEED_VIRTUAL_DTOR - added example and Core Guidelines link to C26436
C26439 SPECIAL_NOEXCEPT - added example and link to Core Guidelines for C26439
C26440 DECLARE_NOEXCEPT - added example and link to Core Guidelines for C26440
C26446 USE_GSL_AT - added an example for C26446
C26447 DONT_THROW_IN_NOEXCEPT - adding example to C26447
C26460 USE_CONST_REFERENCE_ARGUMENTS - added description and example to C26460
C26461 USE_CONST_POINTER_ARGUMENTS: - added description and example to C26461
C26462 USE_CONST_POINTER_FOR_VARIABLE - added description and example to C26462
C26465 NO_CONST_CAST_UNNECESSARY - added example to C26465
C26466 NO_STATIC_DOWNCAST_POLYMORPHIC - added Example to C26466
C26471 NO_REINTERPRET_CAST_FROM_VOID_PTR - added Example to C26471
C26474 NO_IMPLICIT_CAST - updated to clarify base/derived cases
C26482 NO_DYNAMIC_ARRAY_INDEXING - added example to C26482
C26483 STATIC_INDEX_OUT_OF_RANGE - added example to C26483
C26490 NO_REINTERPRET_CAST - added example to C26490
C26492 NO_CONST_CAST - added example to C26492
C26493 NO_CSTYLE_CAST - added example to C26493
C26494 VAR_USE_BEFORE_INIT - added example to C26494
C26495 MEMBER_UNINIT - updated examples and links in C26495
C26496 USE_CONST_FOR_VARIABLE - added example to C26496
C26497 USE_CONSTEXPR_FOR_FUNCTION - added example to C26497

Linux with Microsoft C++ in Visual Studio


New ar ticles
Configure a Linux CMake project in Visual Studio
Updated ar ticles
Configure a Linux CMake project in Visual Studio - updated to reflect latest UI
ConnectionManager reference - added commands for modify, clean
Create a Linux MSBuild C++ project in Visual Studio - updated instructions to create a Linux project
Deploy, run, and debug your Linux MSBuild project - added GDB Path
C/C++ compiler and tools errors and warnings
New ar ticles
Compiler Warning (level 4) C4388 - added warning C4388, updated Visual Studio 16.7 warnings
Updated ar ticles
Compiler Error C3381 - address cpp-docs 2493; update remarks and example
Compiler Warning (level 3) C4018 - updated Visual Studio 16.7 warnings
Compiler Warning (level 4) C4389 - updated Visual Studio 16.7 warnings
Compiler Warnings by compiler version - updated Visual Studio 16.7 warnings
Compiler warnings C4800 through C5999 - updated Visual Studio 16.7 warnings
C/C++ compiler intrinsics and assembly language
Updated ar ticles
C++ conformance improvements in Visual Studio - updated to Visual Studio 16.8 release notes
C++ in Visual Studio - updated DevCom and Microsoft Docs Q&A links
Microsoft C/C++ help and community - updated DevCom and Microsoft Docs Q&A links
Microsoft C/C++ language conformance - updated C++20 library conformance table, update language
feature table for Visual Studio 16.7
C++ in Visual Studio
Updated ar ticles
__restrict
union - fixed code snippet
if-else statement (C++) - added description for if/else grammar
C/C++ projects and build systems
New ar ticles
.vcxproj files and wildcards
/headerUnit (Use header unit IFC)
/module:exportHeader (Create header units)
/module:reference (Use named module IFC)
/translateInclude (Translate include directives into import directives)
/Zc:preprocessor (Enable preprocessor conformance mode)

Updated ar ticles
/clr (Common Language Runtime Compilation) - added description for /clr
/permissive- (Standards conformance) - updated to Visual Studio 16.8 release notes
Importing data using __declspec(dllimport) - updated example
pgosweep - added more pgosweep options
C++ porting and upgrade guide
Updated ar ticles
How to: Use existing C++ code in a Universal Windows Platform app - reworked for clarity and updated
examples
C++ Standard Library (STL) reference
New ar ticles
<bit>
<bit> functions
endian enum

Updated ar ticles
<bit> functions - updated nodiscard syntax
<ios> typedefs - updated example
basic_string_view Class - added starts_with() , ends_with()
basic_string Class - added _starts_with() , ends_with()
ios_base Class
map class
multimap Class - added contains()
multiset Class - added contains()
set Class - added contains()
unordered_map Class - added contains()
unordered_multimap Class - added contains()
unordered_multiset Class - added contains()
unordered_set Class - added contains()

Community contributors
The following people contributed to the C++, C, and Assembler docs during this period. Thank you! See
Microsoft Docs contributor guide overview if you'd like to learn how to contribute.
BeardedFish - Darian B. (1)
codevenkat (1)
definedrisk - Ben (3)
eltociear - Ikko Ashimine (1)
fsb4000 - Igor Zhukov (1)
Jaiganeshkumaran - Jaiganesh Kumaran (1)
jogo- (1)
justanotheranonymoususer (1)
matrohin - Dmitry Matrokhin (1)
mhemmit (1)
MSDN-WhiteKnight - MSDN.WhiteKnight (1)
OdinTemple - Odin Temple (1)
r00tdr4g0n - r00tdr4g0n (1)
sebkraemer - Sebastian Krämer (1)
vtjnash - Jameson Nash (1)
yecril71pl - Christopher Yeleighton (4)
Youssef1313 - Youssef Victor (1)
zecozephyr - Jonathan Bailey (1)
C++ Conformance improvements, behavior
changes, and bug fixes in Visual Studio 2019
9/21/2021 • 69 minutes to read • Edit Online

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 ar ticle .
This document lists the changes in Visual Studio 2019. For a guide to the 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.

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 starting in Visual Studio 2019
version 16.11), 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 :
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 :

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
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
now creates a temporary, as required by the standard. In Visual Studio 2017, the following code compiles
without warnings. In Visual Studio 2019, the compiler raises warning C4172:

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:

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:

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:

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 .

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_castis 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:

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 :

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:

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:
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:

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:

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 :

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:
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.

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:

// 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 C7552 in both Visual Studio 2017 15.9 and in Visual Studio 2019:

#include <cstdio>

int f()
{
int y = 1724;
int x = 0xdeadbeef;

auto lambda = [&]


{
__asm { // C7552: 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:
#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
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

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

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 starting in Visual Studio 2019 version 16.11).
The following example produces deprecation warning C4996 for std::identity (defined in <type_traits>) in
Visual Studio 2017:

#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 :
#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 starting in Visual Studio 2019 version 16.11) 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:

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:

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 starting in Visual Studio
2019 version 16.11).
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 starting in Visual Studio
2019 version 16.11).
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) 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:

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:

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 warning when the
/std:c++latest compiler option is enabled ( /std:c++20 starting in Visual Studio 2019 version 16.11):

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:

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 warning when the
/std:c++latest compiler option is enabled ( /std:c++20 starting in Visual Studio 2019 version 16.11):

enum E1 { a };
int main() {
double i = a * 1.1;
}

To avoid the warning, use static_cast to convert the second operand:


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. Starting in Visual Studio 2019 version 16.2, the following code produces C5056 when the
/std:c++latest compiler option is enabled ( /std:c++20 starting in Visual Studio 2019 version 16.11):

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:

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:

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:

#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:


#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:
#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 :

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:

// 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:

#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 will raise C2059: "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:

#include <chrono>

class Foo {
std::chrono::milliseconds::duration TotalDuration{}; // C3646: 'TotalDuration': unknown override
specifier
};

To avoid the error, declare TotalDuration as shown here:

#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. Starting in Visual Studio 2019 version 16.3, the
compiler checks for compatibility. In /permissive- mode, the following code produces errors C2371 and C2733:

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:

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:

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:

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:
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 . That's why the warning is raised. The high-order bits of the variable j are set to 0.

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:

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:

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:

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.

#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:

#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:

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:
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:

#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:

#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:

#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:


#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:

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;
}

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:

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,

#define m()
line m(
) line
The previous output of /E was:

line line
#line 2

The new output of /E is now:

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:

import // Invalid
m; // error C2146: syntax error: missing ';' before identifier 'm'

To resolve the issue, keep the import on the same line:

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:

#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:

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:
#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:

struct S {
S() = delete;
S(int) { }
};

struct U {
U() = delete;
U(int i): s{ i } { }

S s{};
};

U u{ 0 };

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:


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:

#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:

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* :

#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:

// 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);
}

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
Starting in Visual Studio 2019 version 16.6, 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


Starting in Visual Studio 2019 version 16.6, 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:

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:
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. That's why we now support default
argument import in C++/CLI. This change can break existing code where multiple overloads are declared, as in
this example:

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:

(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:

#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:
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:

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:

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:

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:

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:

// 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:

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.

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.

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:
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:

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:
// 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.

// 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:
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:

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:

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:
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:

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:

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 .

// /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 .

// /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. 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 .

// /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.
// /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> .

// /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.

// /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.

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:

O P T IO N DESC RIP T IO N

/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- .

/Zc:lambda- Standard lambda processing is required for C++20 Modules


and is implied by /std:c++20 mode or later.
O P T IO N DESC RIP T IO N

/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:

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:
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). With
this change, code that previously bound a reference to a temporary 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.
This sample shows the changed behavior:

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:
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:

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:

#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) . Starting in Visual Studio 2019 version 16.9, 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:

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. That's because the conversion sequences in
the two expressions are no better or worse than each other, so 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:

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:
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:

$ 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:

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:

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. Starting in Visual Studio 2019 version 16.10, the overload resolution behavior is
changed to use the correct overload.
This change can also correct the chosen overload in some other situations:
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


Starting in Visual Studio 2019 version 16.10, 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:

// 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:

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. Starting in Visual Studio 2019
version 16.10, this example now compiles correctly.
Unfortunately, this change can break existing code, as in this example:

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. That'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. Starting in Visual Studio 2019 version 16.10, an explicit specialization is no longer implicitly
marked as inline in /permissive- mode. Consider this example:

// s.h
template<typename T>
struct S {
int f() { return 1; }
};
template<> int S<int>::f() { return 2; }

// s.cpp
#include "s.h"

// main.cpp
#include "s.h"

int main()
{
}

To address the linker error in the above example, add inline explicitly to S<int>::f :

template<> inline int S<int>::f() { return 2; }

Deduced return type name mangling


Starting in Visual Studio 2019 version 16.10, the compiler changed how it generates mangled names for
functions that have deduced return types. For example, consider these functions:

auto f() { return 0; }


auto g() { []{}; return 0; }

Earlier versions of the compiler would generate these names for the linker:

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:
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:

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:

// a.cpp
auto f() { return 1; }

// 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:

static [[nodiscard]] int f() { return 1; }

Starting in Visual Studio 2019 version 16.10, the compiler emits level 4 warning C5240 instead:

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:

[[nodiscard]] static int f() { return 1; }

Warning for include directives with system header-names in module purview


Starting in Visual Studio 2019 version 16.10, 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:
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:

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; :

#include <vector>
export module m;

export
void f(std::vector<int>);

Warning for unused internal linkage functions


Starting in Visual Studio 2019 version 16.10, 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:

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:

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


Starting in Visual Studio 2019 version 16.10, 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:
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:

S2 s2{ { 1, 2 }, 3 };

Correctly detect if a const object isn't initialized


Starting in Visual Studio 2019 version 16.10, the compiler now emits error C2737 when you attempt to define a
const object that isn't fully initialized:

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:

struct S {
int i = 1;
int j = 2;
};

See also
Microsoft C/C++ language conformance
C++ Conformance improvements, behavior
changes, and bug fixes in Visual Studio 2017
8/17/2021 • 52 minutes to read • Edit Online

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 ar ticle .
This document lists the changes in Visual Studio 2017. 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.

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:

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.

// 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.
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.

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:

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 passing such objects, the compiler simply makes a bitwise copy and doesn't call the constructor
or destructor.
#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,

std::atomic<int> i(0);
printf("%i\n", i.load());

or else use a static cast to convert the object before passing it:

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.

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:

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:

#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.

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 to 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:
#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:

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:

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.
//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:

#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:

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:

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:

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:

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:

#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:

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:

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:

#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:

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:

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 :

#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:

#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:

__declspec(noinline) extern "C" HRESULT __stdcall // C4768: __declspec attributes before linkage
specification are ignored

To fix the warning, put extern "C" first:

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:

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:

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:
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:

#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:

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:

#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:

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:

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:

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:
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:

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
}
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.

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.

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
}

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:

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:

#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;
}

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:

#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:

#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");

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:
#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:

void f() {
char s[2] = {0}; // C4189. Either use the variable or remove it.
}

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 only */
#pragma warning(disable:4001) // C4619
#pragma warning(disable:4179)
// single line comment
//* single line comment */

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.

__declspec(noinline) extern "C" HRESULT __stdcall // C4768

warning C4768: __declspec attributes before linkage specification are ignored

To fix the error, place the linkage specification before the __declspec attribute:

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:

#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.

extern constexpr int x = 10;

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:

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:
#include <typeinfo>

struct S;

void f() { typeid(S); } //C2027 in 15.5

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:

#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:

#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:

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:

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:

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:

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:
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:

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> :
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:
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:

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:

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:
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 :

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.

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:

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:

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:

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.

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' :

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.

[[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:
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:

#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:

#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:
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:

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):

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. That'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:

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; .


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:

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:

#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:

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:

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:

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>:

#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:
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:

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:

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:

// 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:

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.

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:

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:

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.
#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:

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 :
#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:

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:

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
9/3/2021 • 27 minutes to read • Edit Online

Standards conformance for the Microsoft C/C++ compiler in Visual Studio (MSVC) is a work in progress. Here's
a summary of our ISO Standard C and C++ language and library conformance by Visual Studio version. Each
C++ compiler and standard library feature name links to the ISO Standard C++ proposal paper that describes
the feature, if one is available at publication time. The Suppor ted 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.

NOTE
There are no binary breaking changes between Visual Studio 2015, Visual Studio 2017, and Visual Studio 2019. For more
information, see C++ binary compatibility between Visual Studio 2015, 2017, and 2019

C++ compiler features


F EAT URE SUP P O RT ED

C++03/11 Core language features Suppor ted

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++14 Core language features Suppor ted

N3323 Tweaked wording for contextual conversions VS 2013

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


F EAT URE SUP P O RT ED

N3778 Sized deallocation VS 2015

N3781 Digit separators VS 2015

N3651 Variable templates VS 2015.2

N3652 Extended constexpr VS 2017 15.0

N3653 Default member initializers for aggregates VS 2017 15.0

C++17 Core language features Suppor ted

N4086 Removing trigraphs VS 2010 14

N3922 New rules for auto with braced-init-lists VS 2015 14

N4051 typename in template template-parameters VS 2015 14

N4266 Attributes for namespaces and enumerators VS 2015 14

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

VS 2017 15.3 17
P0028R4 Using attribute namespaces without
repetition

P0061R1 __has_include VS 2017 15.3 14

VS 2017 15.3 17
P0138R2 Direct-list-init of fixed enums from
integers

P0170R1 constexpr lambdas VS 2017 15.3 17

P0189R1 [[nodiscard]] attribute VS 2017 15.3 17


F EAT URE SUP P O RT ED

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 bindings VS 2017 15.3 17

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-specifications VS 2017 15.5 17

P0012R1 Adding noexcept to the type system VS 2017 15.5 17

P0035R4 Over-aligned dynamic memory allocation VS 2017 15.5 17

P0386R2 Inline variables VS 2017 15.5 17

VS 2017 15.5 17
P0522R0 Matching template template-parameters 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

VS 2017 15.7 17
P0091R3 Template argument deduction for class
templates
P0512R0 Class template argument deduction issues

VS 2017 15.7 17
P0127R2 Declaring non-type template 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


F EAT URE SUP P O RT ED

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 repor ts) Suppor ted

VS 2017 15.7 17
P0702R1 Fixing class template argument deduction
for initializer-list ctors

VS 2019 16.0 17
P0961R1 Relaxing the structured bindings
customization point finding rules

VS 2019 16.0 17
P0969R0 Allowing structured bindings to accessible
members

P0588R1 Simplifying implicit lambda capture VS 2019 16.4 17

P1771R1 [[nodiscard]] for constructors VS 2019 16.4 17

VS 2019 16.4 17
P1825R0 Merged wording for P0527R1 and P1155R3,
more implicit moves

P0929R2 Checking for abstract class types VS 2019 16.5 17

VS 2019 16.5 17
P0962R1 Relaxing the range-for loop customization
point finding rules

Partial in VS 2019 16.7 E


P0859R0 CWG 1581: When are constexpr 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 Suppor ted

VS 2015 14
P0641R2 const mismatch with defaulted copy
constructor

VS 2015 14
P0704R1 Fixing const lvalue ref-qualified pointers
to members
F EAT URE SUP P O RT ED

VS 2015 14
P1041R4 Make char16_t/char32_t string literals be
UTF-16/32

VS 2017 15.0 14
P1330R0 Changing the active member of a union
inside constexpr

VS 2017 15.7 14
P0972R0 noexcept For <chrono> zero(), min(), max()

VS 2019 16.0 20
P0515R3 Three-way (spaceship) comparison operator
<=>

P0941R2 Feature-test macros VS 2019 16.0 14

VS 2019 16.0 20
P1008R1 Prohibiting aggregates with user-declared
constructors

P0329R4 Designated initialization VS 2019 16.1 20

VS 2019 16.1 20
P0846R0 ADL and function templates that are not
visible

P0409R2 Allowing lambda-capture [=, this] VS 2019 16.2 20

VS 2019 16.2 20
P0428R2 Familiar template syntax for generic
lambdas

VS 2019 16.2 20
P0624R2 Default constructible and assignable
stateless lambdas

VS 2019 16.2 20
P0780R2 Allowing pack expansion in lambda init-
capture

VS 2019 16.2 20
P0806R2 Deprecate implicit capture of this via [=]

VS 2019 16.2 20
P1120R0 Consistency improvements for <=> and 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


F EAT URE SUP P O RT ED

VS 2019 16.3 20
P1084R2 Today's return-type-requirements are
insufficient

P0892R2 Conditional explicit VS 2019 16.4 20

VS 2019 16.4 20
P1091R3 Extending structured bindings to be 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

VS 2019 16.5 20
P0306R4 Adding __VA_OPT__ for comma omission and
comma deletion

P0614R1 Range-based for-loops with initializers VS 2019 16.5 20

VS 2019 16.5 20
P0683R1 Default member initializers for bit-fields

P1002R1 try-catch blocks in constexpr functions VS 2019 16.5 20

VS 2019 16.5 20
P1161R3 Deprecate uses of the comma operator in
subscripting expressions

P1301R4 [[nodiscard("message")]] VS 2019 16.5 20

VS 2019 16.5 20
P1703R1 Recognizing header unit imports requires
full preprocessing

P1946R0 Allow defaulting comparisons by value VS 2019 16.5 20

P0479R5 [[likely]] and [[unlikely]] attributes VS 2019 16.6 20

VS 2019 16.6 14
P0692R1 Relaxing access checking on specializations

VS 2019 16.6 20
P0732R2 Class types in non-type template parameters

VS 2019 16.6 14
P1139R2 Address wording issues related to ISO 10646

VS 2019 16.6 20
P1907R1 Inconsistencies with non-type template
parameters
F EAT URE SUP P O RT ED

VS 2019 16.6 20
P1971R0 US053: Mandate the return type for
return_void and return_value to be void

VS 2019 16.6 20
P1971R0 US065: Apply Coroutines issue 24 from
P0664R8

P1979R0 Resolution to US086 VS 2019 16.6 20

VS 2019 16.7 20
P0388R4 Permit conversions to arrays of unknown
bound

VS 2019 16.7 20
P0466R5 Layout-compatibility and Pointer-
interconvertibility Traits

VS 2019 16.7 20
P0722R3 Efficient sized delete for variable sized
classes

P1094R2 Nested inline namespaces VS 2019 16.7 20

P1152R4 Deprecating volatile VS 2019 16.7 20

VS 2019 16.7 20
P1331R2 Permitting trivial default initialization
in constexpr contexts

VS 2019 16.7 20
P1358R0 2310: Type completeness and derived-to-base
pointer conversions

VS 2019 16.7 20
P1452R2 On the non-uniform semantics of return-
type-requirements

VS 2019 16.7 20
P1616R1 Using unconstrained TTPs with constrained
templates

P1814R0 CTAD for alias templates VS 2019 16.7 20

P1816R0 CTAD for aggregates VS 2019 16.7 20

VS 2019 16.7 DR
P1957R1 Converting from T* to bool should be
considered narrowing (re: US 212)

VS 2019 16.7 20
P1968R0 CWG 2282: Consistency with mismatched
aligned/non-over-aligned allocation/deallocation
functions
F EAT URE SUP P O RT ED

VS 2019 16.7 20
P1969R0 CWG 2280: Matching a usual deallocation
function with placement new

VS 2019 16.7 20
P1969R0 CWG 2382: Array allocation overhead for
non-allocating placement new

P1969R0 CWG 2441: Inline function parameters VS 2019 16.7 20

VS 2019 16.7 20
P1971R0 US052: Non-executed return statements in
coroutines

VS 2019 16.7 20
P1972R0 US105: Check satisfaction of constraints
for non-templates when forming pointer to function

VS 2019 16.7 20
P1980R0 CA096: Declaration matching for non-
dependent requires-clauses

P2082R1 Fixing CTAD for aggregates VS 2019 16.7 20

P2085R0 Consistent defaulted comparisons VS 2019 16.7 20

VS 2019 16.7 20
P2103R0 US033: Allow "import" inside linkage-
specifications

VS 2019 16.7 20
P2107R0 US064: Copy semantics of coroutine
parameters

P0912R5 Coroutines VS 2019 16.8 20

P1103R3 Modules VS 2019 16.8 20

P0315R4 Allowing lambdas in unevaluated contexts VS 2019 16.8 20

VS 2019 16.8 20
P0848R3 Conditionally trivial special member
functions

VS 2019 16.8 20
P0960R3 Allow initializing aggregates from a
parenthesized list of values

P1766R1 Mitigating minor modules maladies VS 2019 16.8 20

VS 2019 16.8 20
P1811R0 Relaxing redefinition restrictions for re-
exportation robustness
F EAT URE SUP P O RT ED

VS 2019 16.8 20
P1874R1 Dynamic Initialization Order of Non-Local
Variables in Modules

VS 2019 16.8 20
P1975R0 Fixing the wording of parenthesized
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

VS 2019 16.9 20
P1064R0 Allowing virtual function calls in constant
expressions

VS 2019 16.9 20
P1141R2 Yet another approach for constrained
declarations

VS 2019 16.9 20
P1327R1 Allowing dynamic_cast, polymorphic typeid
in constant expressions

VS 2019 16.9 20
P1668R1 Permitting unevaluated inline assembly 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

N/A
P0735R1 Interaction of memory_order_consume with
release sequences

P1236R1 Signed integers are two's complement N/A

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.

F EAT URE SUP P O RT ED

C++14 Standard librar y features Suppor ted

N3462 SFINAE-Friendly result_of VS 2015.2


F EAT URE SUP P O RT ED

N3302 constexpr For <complex> VS 2015

N3469 constexpr For <chrono> VS 2015

N3470 constexpr For <array> VS 2015

VS 2015
N3471 constexpr For <initializer_list>, <tuple>,
<utility>

N3545 integral_constant::operator()() VS 2015

VS 2015
N3642 UDLs For <chrono>, <string> (1729ms, "meow"s,
etc.)

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

VS 2015
N3669 Fixing constexpr Member Functions Without
const

N3670 get<T>() VS 2015

VS 2015
N3671 Dual-Range equal(), is_permutation(),
mismatch()

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

VS 2015
N3891 Renaming shared_mutex (Timed) To
shared_timed_mutex

N3346 Minimal Container Element Requirements VS 2013


F EAT URE SUP P O RT ED

VS 2013
N3421 Transparent Operator Functors (less<>, etc.)

VS 2013
N3655 Alias Templates For <type_traits> (decay_t,
etc.)

N3656 make_unique() VS 2013

C++17 Standard librar y features Suppor ted

LWG 2221 Formatted output operator for nullptr VS 2019 16.1

N3911 void_t VS 2015 14

N4089 Safe Conversions In unique_ptr<T[]> VS 2015 14

N4169 invoke() VS 2015 14

VS 2015 F
N4190 Removing auto_ptr, random_shuffle(), And Old
<functional> Stuff

N4258 noexcept Cleanups VS 2015 14

N4259 uncaught_exceptions() VS 2015 14

N4277 Trivially Copyable reference_wrapper VS 2015 14

VS 2015 14
N4279 insert_or_assign()/try_emplace() For
map/unordered_map

N4280 size(), empty(), data() VS 2015 14

VS 2015 14
N4366 Precisely Constraining unique_ptr Assignment

N4387 Improving pair And tuple VS 2015.2 14

N4389 bool_constant VS 2015 14

N4508 shared_mutex (Untimed) VS 2015.2 14

VS 2013 14
N4510 Supporting Incomplete Types In
vector/list/forward_list

N4562 Library Fundamentals: <algorithm> sample() VS 2017 15.0

N4562 Library Fundamentals: <any> VS 2017 15.0


F EAT URE SUP P O RT ED

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()

VS 2015.2 14
P0006R0 Variable Templates For Type Traits
(is_same_v, etc.)

P0007R1 as_const() VS 2015.2 14

VS 2015.2 14
P0013R1 Logical Operator Type Traits (conjunction,
etc.)

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

VS 2017 15.3 17
P0031R0 constexpr For <array> (Again) And
<iterator>

VS 2017 15.0
P0032R3 Homogeneous Interface For
variant/any/optional

P0033R1 Rewording enable_shared_from_this VS 2017 15.5 14

P0040R3 Extending Memory Management Tools VS 2017 15.3 17


F EAT URE SUP P O RT ED

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

VS 2017 15.3 17
P0154R1 hardware_destructive_interference_size,
etc.

P0156R0 Variadic lock_guard VS 2015.2 14

VS 2017 15.3 17
P0156R2 Renaming Variadic lock_guard to scoped_lock

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
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


F EAT URE SUP P O RT ED

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

VS 2017 15.5 17
P0302R1 Removing Allocator Support In std::function

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

VS 2017 15.3 14
P0418R2 atomic compare_exchange memory_order
Requirements

P0426R1 constexpr For char_traits VS 2017 15.7

VS 2017 15.7
P0433R2 Integrating template deduction for class
templates into the 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

VS 2017 15.0
P0504R0 Revisiting
in_place_t/in_place_type_t<T>/in_place_index_t<I>

P0505R0 constexpr For <chrono> (Again) VS 2017 15.3 17

VS 2017 15.0
P0510R0 Rejecting variants Of Nothing, Arrays,
References, And Incomplete Types

P0513R0 Poisoning hash VS 2017 15.3 14


P0599R1 noexcept hash

P0516R0 Marking shared_future Copying As noexcept VS 2017 15.3 14


F EAT URE SUP P O RT ED

VS 2017 15.3 14
P0517R0 Constructing future_error From future_errc

P0521R0 Deprecating shared_ptr::unique() VS 2017 15.5 17

VS 2017 15.3 14
P0558R1 Resolving atomic<T> Named Base Class
Inconsistencies

P0595R2 std::is_constant_evaluated() VS 2019 16.5 20

VS 2017 15.317
P0602R4 Propagating Copy/Move Triviality In
variant/optional

VS 2017 15.3 17
P0604R0 Changing is_callable/result_of To
invoke_result, is_invocable, is_nothrow_invocable

P0607R0 Inline Variables for the Standard Library VS 2017 15.5 17

P0618R0 Deprecating <codecvt> VS 2017 15.5 17

P0682R1 Repairing Elementary String Conversions VS 2015 15.7 17

C++20 Standard librar y features Suppor ted

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

P1164R1 Making create_directory() Intuitive VS 2019 16.0 20

P0550R2 remove_cvref VS 2019 16.0 20

P0318R1 unwrap_reference, unwrap_ref_decay VS 2019 16.1 20

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

P0769R2 shift_left(), shift_right() VS 2019 16.1 20


F EAT URE SUP P O RT ED

P0887R1 type_identity VS 2019 16.1 20

VS 2019 16.2 20
P0020R6 atomic<float>, atomic<double>, atomic<long
double>

P0463R1 endian VS 2019 16.2 20

VS 2019 16.2 20
P0482R6 char8_t: A type for UTF-8 characters and
strings

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

VS 2019 16.2 20
P0771R1 noexcept For std::function's Move
Constructor

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

VS 2019 16.3 20
P0919R3 Heterogeneous Lookup For Unordered
Containers

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

VS 2019 16.5 20
P0556R3 <bit> ispow2(), ceil2(), floor2(), log2p1()

P0595R2 is_constant_evaluated() VS 2019 16.5 20


F EAT URE SUP P O RT ED

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

VS 2019 16.5 20
P1227R2 Signed std::ssize(), Unsigned span::size()

P1355R2 Narrow Contract For ceil2() VS 2019 16.5 20

P1357R1 is_bounded_array, is_unbounded_array VS 2019 16.5 20

P1612R1 Relocating endian To <bit> VS 2019 16.5 20

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

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

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

P0879R0 constexpr for swapping functions VS 2019 16.6 20

P0883R2 Fixing atomic initialization VS 2019 16.6 14


F EAT URE SUP P O RT ED

VS 2019 16.6 14
P0935R0 Eradicating Unnecessarily Explicit Default
Constructors

VS 2019 16.6 20
P1006R1 constexpr For
pointer_traits<T*>::pointer_to()

VS 2019 16.6 14
P1165R1 Consistently Propagating Stateful
Allocators In basic_string's operator+()

VS 2019 16.6 20
P1423R3 char8_t backward compatibility remediation

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

VS 2019 16.7 20
P0528R3 Atomic Compare-And-Exchange With Padding
Bits

P0586R2 Integer comparison functions VS 2019 16.7 20

P0674R1 make_shared() For Arrays VS 2019 16.7 20

VS 2019 16.7 20
P0718R2 atomic<shared_ptr<T>>, atomic<weak_ptr<T>>

P1023R0 constexpr For std::array Comparisons VS 2019 16.7 20

P1115R3 erase()/erase_if() Return size_type VS 2019 16.7 20

VS 2019 16.7 20
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()

P1964R2 Replacing boolean With boolean-testable VS 2019 16.7 20

VS 2019 16.7 20
P1976R2 Fixed-size span construction from dynamic
range
F EAT URE SUP P O RT ED

P2091R0 Issues with range access CPOs VS 2019 16.7 20

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

P0019R8 atomic_ref VS 2019 16.8 20

VS 2019 16.8 20
P0528R3 Library support for atomic compare-and-
exchange with padding 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

VS 2019 16.8 20
P1123R0 Editorial Guidance for merging P0019r8 and
P0528r3

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

VS 2019 16.9 20
P0768R1 Library Support For The Spaceship
Comparison Operator <=>

P1007R3 assume_aligned() VS 2019 16.9 20

VS 2019 16.9 20
P1020R1 Smart Pointer Creation With Default
Initialization

P1135R6 The C++20 Synchronization Library VS 2019 16.9 20

VS 2019 16.9 20
P1771R1 Library support for [[nodiscard]] for
constructors
F EAT URE SUP P O RT ED

P0053R7 <syncstream> VS 2019 16.10 20


P0753R2 osyncstream Manipulators

P0355R7 <chrono> Calendars And Time Zones VS 2019 16.10 20ab i

VS 2019 16.10 20
P0408R7 Efficient access To basic_stringbuf's
buffer

VS 2019 16.10 20
P0466R5 Library support for layout-compatibility
and pointer-interconvertibility traits

VS 2019 16.10 20
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

P0645R10 <format> Text Formatting VS 2019 16.10 20ab i

VS 2019 16.10 20
P0784R7 Library support for more constexpr
containers

P0896R4 <ranges> VS 2019 16.10 20ab i

P0980R1 constexpr std::string VS 2019 16.10 20

P1004R2 constexpr std::vector VS 2019 16.10 20

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

N/A
P1285R0 Improving Completeness Requirements For
Type Traits

C++23 Standard librar y features Suppor ted

P0881R7 <stacktrace> No

P0943R6 Supporting C Atomics In C++ No


F EAT URE SUP P O RT ED

P1048R1 is_scoped_enum No

No
P1679R3 contains() For
basic_string/basic_string_view

P1682R3 to_underlying() For Enumerations No

P2162R2 Inheriting From variant No

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


F EAT URE SUP P O RT ED

C99 Standard librar y features Suppor ted

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 ( VS 2015


math_errhandling )

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

va_copy macro VS 2015


F EAT URE SUP P O RT ED

Additional strftime conversion specifiers Partial in VS 2015 L

C11 Standard librar y features Suppor ted

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> No

Atomic support <stdatomic.h> No

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

Supported values
No Not yet implemented.
Par tial 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.
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, leaving 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 our 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 our implementation, new compiler warnings for exception specification issues have been
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 Starting in Visual Studio 2019 version 16.6, the compiler fully implements the C99 preprocessor via the
/Zc:preprocessor option. (Before version 16.6, starting in Visual Studio 2017 version 15.8, the compiler
provides support for the 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 every algorithm is parallelized in
every case. The most important algorithms have been parallelized, and execution policy signatures are provided
even where we don't parallelize algorithms. Our implementation's 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 ,
, equal , exclusive_scan , find ,
count_if
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 may be infeasible:
partial_sort , partial_sort_copy
These algorithms haven't been evaluated yet. We may 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. The experimental
implementation will be removed 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 .
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 . We'll make these features available
under /std:c++20 after reaching agreement 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 starting in Visual Studio 2019 version 16.11.
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.
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 10 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.
2104 C11 library support for this feature requires Windows 10 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
Supported Platforms (Visual C++)
3/6/2021 • 2 minutes to read • Edit Online

Apps built by using Visual Studio can be targeted to various platforms, as follows.

O P ERAT IN G SY ST EM X86 X64 A RM A RM 64****

Windows XP X* X*

Windows Server X* X*
2003

Windows Vista X X

Windows Server X X
2008

Windows 7 X X

Windows Server X X
2012 R2

Windows 8 X X X

Windows 8.1 X X X

Windows 10 X X X X

Android ** X X X X

iOS ** X X X X

Linux *** X X X X

* You can use the Windows XP platform toolset 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 this platform toolset, see Configuring Programs for Windows XP. For additional
information on changing the platform toolset, see How to: Modify the Target Framework and Platform Toolset.
** 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 the iOS simulator,
Microsoft Visual Studio Emulator for Android, and some Android devices. Use ARM configurations to build for
iOS devices and most Android devices.
*** 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.
**** ARM64 support is available in Visual Studio 2017 and later.
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
C++ Tools and Features in Visual Studio Editions
3/6/2021 • 9 minutes to read • Edit Online

The following C++ features are available in Visual Studio 2019. 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 7.0, targeting x86 or x64 (CMake support only). Other Clang versions
might work but are not officially supported.
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 v142 - VS 2019 C++ x64/x86 build tools (v14.21)
Windows 10 SDK (10.0.17763.0)
Just-In-Time debugger
C++ profiling tools
C++ CMake tools for Windows
C++ ATL for v142 build tools (x86 & x64)
Test Adapter for Boost.Test
Test Adapter for Google Test
Live Share
IntelliCode
IntelliTrace (Enterprise only)
C++ MFC for v142 build tools (x86 & x64)
C++/CLI support for v142 build tools (14.21)
C++ Modules for v142 build tools (x64/x86 – experimental)
Clang compiler for Windows
IncrediBuild - Build Acceleration
Windows 10 SDK (10.0.17134.0)
Windows 10 SDK (10.0.16299.0)
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
Windows Universal C Runtime
C++ for Linux Development
Optional Components:
C++ CMake tools for Linux
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 (10.0.17763.0)
Optional Components:
IntelliCode
IntelliTrace (Enterprise only)
USB Device Connectivity
C++ (v142) Universal Windows Platform tools
C++ (v141) Universal Windows Platform tools
Graphics debugger and GPU profiler for DirectX
Windows 10 SDK (10.0.18362.0)
Windows 10 SDK (10.0.17134.0)
Windows 10 SDK (10.0.16299.0)
Architecture and analysis tools
C++ Game Development
Included:
C++ core features
Windows Universal C Runtime
C++ 2019 Redistributable Update
MSVC v142 - VS 2019 C++ x64/x86 build tools (v14.21)
Optional Components:
C++ profiling tools
Windows 10 SDK (10.0.17763.0)
IntelliCode
IntelliTrace (Enterprise only)
Windows 10 SDK (10.0.17134.0)
Windows 10 SDK (10.0.16299.0)
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 (R16B)
Apache Ant (1.9.3)
C++ Android development tools
IntelliCode
Google Android Emulator (API Level 25) (local install)
Intel Hardware Accelerated Execution Manager (HAXM) (local install)
Android NDK (R16B) (32bit)
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

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
The following tables show Visual C++ features that are available in Visual Studio 2017. An X in a cell indicates
that the feature is available; an empty cell indicates that the feature is not available. Notes in parentheses
indicate that a feature is available, but restricted.

Platforms
VISUA L ST UDIO VISUA L ST UDIO VISUA L ST UDIO
EXP RESS F O R EXP RESS F O R C O M M UN IT Y / P RO F E VISUA L ST UDIO
P L AT F O RM W IN DO W S 10 W IN DO W S DESK TO P SSIO N A L EN T ERP RISE

Windows Desktop X X X

Universal Windows X X X
Platform ((phone,
tablet, PC, Xbox, IoT,
and HoloLens))

Linux X X

Microsoft Store 8.1 X X

Windows Phone 8.0 X X

Android X X

iOS X X

Compilers
VISUA L ST UDIO VISUA L ST UDIO VISUA L ST UDIO
EXP RESS F O R EXP RESS F O R P RO F ESSIO N A L / VISUA L ST UDIO
C O M P IL ER W IN DO W S W IN DO W S DESK TO P C O M M UN IT Y EN T ERP RISE

MSVC 32-bit X86 X X X X


compiler

X86_arm cross- X X X
compiler

MSVC 64-bit x64 X X


compiler

X86_ x64 cross- X X X X


compiler

Libraries and Headers


VISUA L ST UDIO VISUA L ST UDIO VISUA L ST UDIO
EXP RESS F O R EXP RESS F O R P RO F ESSIO N A L / VISUA L ST UDIO
L IB RA RY O R H EA DER W IN DO W S W IN DO W S DESK TO P C O M M UN IT Y EN T ERP RISE

Windows headers (X) X X X


and libraries and CRT
library

C++ Standard X X X X
Library

ATL X X

MFC X X
VISUA L ST UDIO VISUA L ST UDIO VISUA L ST UDIO
EXP RESS F O R EXP RESS F O R P RO F ESSIO N A L / VISUA L ST UDIO
L IB RA RY O R H EA DER W IN DO W S W IN DO W S DESK TO P C O M M UN IT Y EN T ERP RISE

.NET Framework class X X X


library

C++ Support Library X X X


for .NET

OpenMP 2.0 X X X X

Project Templates
VISUA L ST UDIO VISUA L ST UDIO VISUA L ST UDIO
EXP RESS F O R EXP RESS F O R P RO F ESSIO N A L / VISUA L ST UDIO
T EM P L AT E W IN DO W S W IN DO W S DESK TO P C O M M UN IT Y EN T ERP RISE

XAML Templates for X X X


UWP, Windows 8.1,
Windows Phone 8.0

Direct3D App X X X

DLL (Universal X X X
Windows)

Static Library X X X
(Universal Windows)

Windows Runtime X X X
Component

Unit Test App X X X


(Universal Windows)

ATL Project X X

Class Library (CLR) X X X

CLR Console X X X
Application

CLR Empty Project X X X

Custom Wizard X X

Empty Project X X X

Makefile Project X X X

MFC ActiveX Control X X

MFC Application X X
VISUA L ST UDIO VISUA L ST UDIO VISUA L ST UDIO
EXP RESS F O R EXP RESS F O R P RO F ESSIO N A L / VISUA L ST UDIO
T EM P L AT E W IN DO W S W IN DO W S DESK TO P C O M M UN IT Y EN T ERP RISE

MFC DLL X X

Test Project X X X X

Win32 Console X X X
Application

Win32 Project X X X

Tools
VISUA L ST UDIO VISUA L ST UDIO VISUA L ST UDIO
EXP RESS F O R EXP RESS F O R P RO F ESSIO N A L / VISUA L ST UDIO
TO O L W IN DO W S W IN DO W S DESK TO P C O M M UN IT Y EN T ERP RISE

Incremental Linker X X X X
(Link.exe)

Program X X X
Maintenance Utility
(Nmake.exe)

Lib Generator X X X X
(Lib.exe)

Windows Resource X X X X
Compiler (Rc.exe)

Windows Resource to X X X
Object Converter
(CvtRes.exe)

Browse Information X X X X
Maintenance Utility
(BscMake.exe)

C++ Name X X X X
Undecorator
(Undname.exe)

COFF/PE Dumper X X X X
(Dumpbin.exe)

COFF/PE Editor X X X X
(Editbin.exe)

MASM (Ml.exe) X X

Spy++ X X

ErrLook X X
VISUA L ST UDIO VISUA L ST UDIO VISUA L ST UDIO
EXP RESS F O R EXP RESS F O R P RO F ESSIO N A L / VISUA L ST UDIO
TO O L W IN DO W S W IN DO W S DESK TO P C O M M UN IT Y EN T ERP RISE

AtlTrace X X

Devenv.com X X

Inference Rules X X

Upgrade VCBuild X X X X
.vcproj projects to
MSBuild
(VCUpgrade.exe)

Profile Guided X X
Optimizations

Debugging Features
VISUA L ST UDIO VISUA L ST UDIO VISUA L ST UDIO
EXP RESS F O R EXP RESS F O R P RO F ESSIO N A L / VISUA L ST UDIO
DEB UGGIN G F EAT URE W IN DO W S W IN DO W S DESK TO P C O M M UN IT Y EN T ERP RISE

Native Debugging X X X X

natvis (native type X X X X


visualization)

Graphics Debugging X X X

Managed Debugging X X X

GPU usage X X X

Memory usage X X X

Remote Debugging X X X X

SQL Debugging X X

Static Code Analysis Limited Limited X X

Designers and Editors


VISUA L ST UDIO VISUA L ST UDIO VISUA L ST UDIO
EXP RESS F O R EXP RESS F O R P RO F ESSIO N A L / VISUA L ST UDIO
DESIGN ER O R EDITO R W IN DO W S W IN DO W S DESK TO P C O M M UN IT Y EN T ERP RISE

XAML Designer X X X

CSS Style X X X X
Designer/Editor
VISUA L ST UDIO VISUA L ST UDIO VISUA L ST UDIO
EXP RESS F O R EXP RESS F O R P RO F ESSIO N A L / VISUA L ST UDIO
DESIGN ER O R EDITO R W IN DO W S W IN DO W S DESK TO P C O M M UN IT Y EN T ERP RISE

HTML X X X X
Designer/Editor

XML Editor X X X X

Source Code Editor X X X X

Productivity Features: X X X X
Refactoring,
IntelliSense, C++
Code Formatting

Windows Forms X X X
Designer

Data Designer X X

Native Resource X X
Editor (.rc files)

Resource Editors X X X X

Model editor X X X

Shader designer X X X

Data Features
VISUA L ST UDIO VISUA L ST UDIO VISUA L ST UDIO
EXP RESS F O R EXP RESS F O R P RO F ESSIO N A L / VISUA L ST UDIO
DATA F EAT URE W IN DO W S W IN DO W S DESK TO P C O M M UN IT Y EN T ERP RISE

Data Designer X X

Data Objects X X

Web Services X X

Server Explorer X X

Build and Project Systems


VISUA L ST UDIO VISUA L ST UDIO VISUA L ST UDIO
B UIL D O R P RO JEC T EXP RESS F O R EXP RESS F O R P RO F ESSIO N A L / VISUA L ST UDIO
F EAT URE W IN DO W S W IN DO W S DESK TO P C O M M UN IT Y EN T ERP RISE

Command line builds X X X X


(msbuild.exe)
VISUA L ST UDIO VISUA L ST UDIO VISUA L ST UDIO
B UIL D O R P RO JEC T EXP RESS F O R EXP RESS F O R P RO F ESSIO N A L / VISUA L ST UDIO
F EAT URE W IN DO W S W IN DO W S DESK TO P C O M M UN IT Y EN T ERP RISE

Native Multi- X X X
targeting

Managed Multi- X X X
targeting

Parallel Builds X X X X

Build Customizations X X X X

Property Pages X X X X
Extensibility

Automation and Extensibility


VISUA L ST UDIO VISUA L ST UDIO VISUA L ST UDIO
A UTO M AT IO N A N D EXP RESS F O R EXP RESS F O R P RO F ESSIO N A L / VISUA L ST UDIO
EXT EN SIB IL IT Y W IN DO W S W IN DO W S DESK TO P C O M M UN IT Y EN T ERP RISE

Extensibility Object X X
Models

Code Model X X

Project Model X X

Resource Editor X X
Model

Wizard Model X X

Debugger Object X X
Model

Application Lifecycle Management Tools


VISUA L ST UDIO VISUA L ST UDIO VISUA L ST UDIO
EXP RESS F O R EXP RESS F O R P RO F ESSIO N A L / VISUA L ST UDIO
TO O L W IN DO W S W IN DO W S DESK TO P C O M M UN IT Y EN T ERP RISE

Unit Testing (native X X X X


framework)

Unit Testing X X X
(managed
framework)

Code coverage X

Manual testing X
VISUA L ST UDIO VISUA L ST UDIO VISUA L ST UDIO
EXP RESS F O R EXP RESS F O R P RO F ESSIO N A L / VISUA L ST UDIO
TO O L W IN DO W S W IN DO W S DESK TO P C O M M UN IT Y EN T ERP RISE

Exploratory testing X

Test case X
management

Code map and read-only X


dependency graphs

Code map X
debugging

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
9/21/2021 • 3 minutes to read • Edit Online

Support for C11 and C17 standards requires Visual Studio 2019 version 16.8 or later. To see the documentation
for this version, set the Visual Studio Version selector control for this article to Visual Studio 2019. It's found at
the top of the table of contents on this page.
Support for C11 and C17 standards is available starting in Visual Studio 2019 version 16.8. Support requires an
updated Universal C Runtime (UCRT) and the latest Windows SDK updates, 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. Normally, the Windows SDK is an installable option in the Individual
Components tab in the Visual Studio Installer. That's the recommended way to update the SDK for use with
Visual Studio. However, at the time of writing, the latest Windows SDK isn't available 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 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.

Step 1: Download the Windows 10 SDK


You can download the latest Windows 10 SDK from the Windows 10 SDK page. If you see a message that says
"We are sorry, the page you requested cannot be found," try changing the locale in the URL to en-us.
Choose Download the installer under Windows 10 SDK version 2104 and Server development to begin the
download. Later versions of the Windows SDK will also work.
When the download completes, open the folder for the downloaded file. It's usually your Downloads folder, and
the file is typically named winsdksetup.exe . Right-click on the file to open the file's Proper ties dialog box. On
the General tab, in the Security section, check the Unblock checkbox. Choose OK to save your changes.

Step 2: Install the Windows 10 SDK


Run winsdksetup.exe to start the installation.
On the Specify Location page, select Install the Windows Software Development Kit - <version> to
this computer , and then choose Next . On the Windows Kits Privacy page, select whether to allow Microsoft
to collect insights for the Windows 10 Kits, then choose Next . Choose Accept to accept the license agreement.
On the Select the features you want to install page, select these features:
Windows SDK Signing Tools for Desktop Apps
Windows SDK for UWP Managed Apps
Windows SDK for UWP C++ Apps
Windows SDK for Desktop C++ x86 Apps (if you plan to build for x86)
Windows SDK for Desktop C++ amd64 Apps (if you plan to build for x64)
Windows SDK for Desktop C++ arm Apps (if you plan to build for ARM)
Windows SDK for Desktop C++ arm64 Apps (if you plan to build for ARM64)

Choose Install to install the selected SDK components. The SDK takes a couple of minutes to complete
installation. When it completes, open Visual Studio.

Step 3: Configuring C11 or C17 mode in Visual Studio


In Visual Studio, open a new or existing C project, then open your project's Proper ty Pages dialog.
Set the project to use the Windows 10 SDK you just installed. On the Configuration Proper ties > 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 Proper ties > 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
5/4/2021 • 49 minutes to read • Edit Online

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:
Microsoft Docs samples - C++
Windows samples on GitHub
Windows Dev Center code samples
CodePlex sample archive
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
SA M P L E N A M E DESC RIP T IO N

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.
SA M P L E N A M E DESC RIP T IO N

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


SA M P L E N A M E DESC RIP T IO N

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


SA M P L E N A M E DESC RIP T IO N

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.
SA M P L E N A M E DESC RIP T IO N

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


SA M P L E N A M E DESC RIP T IO N

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


SA M P L E N A M E DESC RIP T IO N

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


SA M P L E N A M E DESC RIP T IO N

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.
SA M P L E N A M E DESC RIP T IO N

Scribble (Windows Forms) A Windows Forms implementation of the Scribble sample,


updated and extended to include new .NET functionality.

STLCLR Demonstrates some of the capabilities available when using


the STL/CLR Library.

COM events samples


SA M P L E N A M E DESC RIP T IO N

COMEvents Demonstrates event handling using COM.

ComTypeLibfor7 samples
SA M P L E N A M E DESC RIP T IO N

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
SA M P L E N A M E DESC RIP T IO N

ccWrapper Demonstrates how to map C/C++ compiler flags from other


compilers to the Visual C++ compiler (cl.exe).

Compiler samples - MASM


SA M P L E N A M E DESC RIP T IO N

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
SA M P L E N A M E DESC RIP T IO N

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
SA M P L E N A M E DESC RIP T IO N
SA M P L E N A M E DESC RIP T IO N

EEAddIn Uses the Expression Evaluator Add-In API to extend the


native debugger expression evaluator.

Fusion samples
SA M P L E N A M E DESC RIP T IO N

TraceMan Provides information about application-dependent


assemblies, and the assemblies' state in the native fusion
cache, in human readable form.

Hilo sample
SA M P L E N A M E DESC RIP T IO N

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
SA M P L E N A M E DESC RIP T IO N

IME Demonstrates how to control the Input Method Editor


mode and how to implement IME level 3.

SatDLL Demonstrates a recommended way to implement


multilingual resources in a Win32 application.

UniRes Demonstrates the use of Unicode resource files.

Language samples - General


SA M P L E N A M E DESC RIP T IO N

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.
SA M P L E N A M E DESC RIP T IO N

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
SA M P L E N A M E DESC RIP T IO N

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.

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


SA M P L E N A M E DESC RIP T IO N

Button Demonstrates use of an in-place active menu, a stock


property page, and the About box control option.
SA M P L E N A M E DESC RIP T IO N

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.

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


SA M P L E N A M E DESC RIP T IO N

ClipArt The ClipArt directory contains sample resources that you


can use to customize the appearance of your application.
SA M P L E N A M E DESC RIP T IO N

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.

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.
SA M P L E N A M E DESC RIP T IO N

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.

VariantUse Demonstrates the use of the variant data type.

ViewEx Multiple views, scroll view, splitter windows.

MFC samples - Internet


SA M P L E N A M E DESC RIP T IO N

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


SA M P L E N A M E DESC RIP T IO N

ACDual Demonstrates how to add dual interface support to an


MFC-based Automation server.
SA M P L E N A M E DESC RIP T IO N

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.

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


SA M P L E N A M E DESC RIP T IO N

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


SA M P L E N A M E DESC RIP T IO N

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.

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.
SA M P L E N A M E DESC RIP T IO N

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.

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.


SA M P L E N A M E DESC RIP T IO N

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.

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


SA M P L E N A M E DESC RIP T IO N

GestureDemo Demonstrates the Windows Touch support in MFC (requires


touch hardware).

TouchDemo Demonstrates the Windows Touch support in MFC (requires


touch hardware).

ODBC samples
SA M P L E N A M E DESC RIP T IO N

odbcsql This sample demonstrates how to use ODBC APIs to


Connect to and access database.

OS samples
SA M P L E N A M E DESC RIP T IO N

GetImage Demonstrates the Windows Image Acquisition (WIA)


application programming interfaces (APIs).

Unix samples
SA M P L E N A M E DESC RIP T IO N

Unix - ccWrapper Demonstrates a wrapper that maps flags from the Sun Forte
and gcc 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.

SA M P L E N A M E DESC RIP T IO N

Background Transfer sample (Windows 8) This sample demonstrates the power-friendly, cost-aware,
and flexible behavior of the Background Transfer API for
Windows Runtime applications. Provided sample scenarios
cover file downloads and uploads.

CryptoWinRT sample (Windows 8) This sample shows how to use the new Cryptography APIs.

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 (Windows 8) This sample demonstrates the use of the HttpClient class
and the 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 sample (Windows 8) This sample shows how to use the
Windows.Devices.Sensors.Accelerometer API. This
sample allows the user to view the acceleration forces along
the X-, Y-, and Z-axes for a 3-axis accelerometer. You can
choose one of three scenarios.

Account picture name sample (Windows 8) This sample demonstrates different ways of getting the
name of the 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 (Windows 8) This sample demonstrates how to use the
ApplicationSettings API 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 for camera sample (Windows 8) This sample demonstrates how to create a Windows Store
device app for a camera. A Windows Store device app is
provided by an IHV or OEM to differentiate the capture
experience for a particular camera.
SA M P L E N A M E DESC RIP T IO N

Getting started with C++ simple blog reader sample The sample demonstrates some basic principles of Windows
(Windows 8) Store app development in native C++ using XAML to define
the user interface. It's a complete working version of the
application discussed on the Windows Developer Center.

Reading and writing data sample (Windows 8) This sample shows how to use the DataReader and
DataWriter classes to store and retrieve data.

Application data sample (Windows 8) This sample shows you how to store and retrieve data that is
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 sample (Windows 8) This sample shows how to use CreateDeviceAccessInstance
and IDeviceIoControl to access a specialized device.

XAML ListView and GridView essentials sample (Windows 8) This sample demonstrates how to use the GridView and
ListView controls.

Animation metrics sample (Windows 8) This sample shows how to use the Animation Metrics APIs in
Windows.UI.Core.AnimationMetrics to access the raw
parameters that define the animations in the Windows
Animation Library.

Playback Manager msAudioCategory sample (Windows 8) This sample demonstrates how to select the correct
msAudioCategory category for an audio-video (AV) stream
to configure it as an audio playback stream.

XAML DirectX 3D shooting game sample (Windows 8) This sample demonstrates the implementation of a simple
first 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.

XAML scrolling, panning, and zooming sample (Windows 8) This sample demonstrates how to use the ScrollViewer
control to pan and zoom.

XAML FlipView control sample (Windows 8) This sample demonstrates how to use the FlipView control
to enable users to flip through a collection.

Gyrometer sensor sample (Windows 8) This sample shows how to use the
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 SDK sample (Windows 8) This sample shows how to create a device app for printers
that can be activated from the tile contract, the
printTaskSettings contract, and from toast displayed by
backgroundTask in response to print driver event.

Background task sample (Windows 8) This sample shows you how to create and register
background tasks 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.
SA M P L E N A M E DESC RIP T IO N

StreamSocket sample (Windows 8) This sample demonstrates the basics of the StreamSocket
class 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 sample (Windows 8) This sample shows how to use scheduled and recurring tile
updates 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 Companion Sample (Windows 8) This sample demonstrates how to select the correct
msAudioCategory category for an audio-video stream to
configure it as an audio playback stream.

OrientationSensor sample (Windows 8) This sample shows how to use the


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 (Windows 8) This sample shows how to create, read, write, copy and
delete a file, 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 (Windows 8) The removable storage sample demonstrates how to
transfer files to and from removable storage devices. This
sample requires a removable storage device connected to
the system, such as a camera, media player, cellular phone,
or a USB thumb drive.

XAML SurfaceImageSource DirectX interop sample (Windows This sample demonstrates how to use a
8) SurfaceImageSource to include DirectX content in your
XAML app. This sample uses both C++ and C#.

Connecting with WebSockets sample (Windows 8) This sample demonstrates how to use WebSockets in a
connected Windows Store app. The sample covers basic
functionality, such as how to make a connection, send and
receive data, and close the connection.

Configure keys for media sample (Windows 8) This sample demonstrates how to configure the hardware
media 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 animations sample (Windows 8) This sample demonstrates how to use the built-in
personality animations in your app.

Toast notifications sample (Windows 8) This sample shows how to use toast notifications: Ones that
appear 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.
SA M P L E N A M E DESC RIP T IO N

Contact Picker app sample (Windows 8) This sample demonstrates how to use the Contact Picker to
select 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 sample (Windows 8) This sample demonstrates how to build a basic 3D game
using 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 sample (Windows 8) This sample demonstrates the implementation of a simple
Windows Store app using DirectX with C++ for postcard
creation using DirectX and XAML interop.

DirectX 3D shooting game sample (Windows 8) This sample demonstrates the implementation of a simple
first person 3-D game using DirectX (Direct3D 11.1,
Direct2D, XInput, and XAudio2) in a C++ app.

XAML AppBar control sample (Windows 8) This sample demonstrates how to use the AppBar control to
present 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.

Date and time formatting sample (Windows 8) This sample demonstrates how to use the
DateTimeFormatter class in the
Windows.Globalization.DateTimeFormatting namespace
to display dates and times according to the user's
preferences.

Secondary tiles sample (Windows 8) This sample shows how to pin and use a secondary tile.
That's a tile 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 sample (Windows 8) This sample uses a polygon shapes puzzle to demonstrate
how to handle pointer input, implement custom hit testing
for touch input, and process manipulations in a Windows
Store app using C++ and DirectX.

Network information sample (Windows 8) This sample demonstrates how to use the Windows Runtime
Network Information APIs.

Input Simplified ink sample (Windows 8) This sample demonstrates how to use ink functionality in
Windows Store apps.

StorageDataSource and GetVirtualizedFilesVector sample This sample shows how to retrieve and display images in the
(Windows 8) user's Pictures Library.

Edge-based gesture invocation sample (Windows 8) This sample shows how to listen for events that occur in
edge-based UI, using the EdgeGesture class.

Check if current session is remote sample (Windows 8) This sample demonstrates the use of
Windows.System.RemoteDesktop API.
SA M P L E N A M E DESC RIP T IO N

Application resources and localization sample (Windows 8) This sample shows how to use application resources to
separate localizable content from application code. The
sample uses the
Windows.ApplicationModel.Resources.Core and
Windows.Globalization namespaces, and
WinJS.Resources .

Context menu sample (Windows 8) This sample shows how to create a context menu and how
to replace the default context menu for text. This sample
uses Windows.UI.Popups API, including the PopupMenu
and the oncontextmenu event.

Geolocation sample (Windows 8) The Geolocation sample demonstrates how to use the
Geolocation 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 (Windows 8) This sample demonstrates how to use a MessageDialog for
displaying dialogs, setting commands and their actions, and
changing the default button. The Windows.UI.Popups
namespace contains the MessageDialog class.

MediaStreamSource media extension sample (Windows 8) This sample shows how to support the Microsoft Silverlight
MediaStreamSource concept in a Windows Store app.

DirectWrite vertical text sample (Windows 8) This sample uses DirectWrite and Direct2D to properly
display vertical text in a custom layout shape.

DXGI swap chain rotation sample (Windows 8) This sample demonstrates the
IDXGISwapChain1::SetRotation method and how you can
use the method in conjunction with prerotated content to
improve presentation performance.

Direct2D custom image effects sample (Windows 8) This sample demonstrates how to implement custom
Direct2D Effects using standard pixel, vertex, and compute
shaders.

DirectX touch input sample (Windows 8) This sample demonstrates touch and mouse navigation of a
3-D environment in a C++ app with Direct3D.

XInput game controller sample (Windows 8) This sample demonstrates the use of the XInput APIs in a
C++ app. It reads input from an Xbox game controller and
displays data about the analog stick movements and button
presses.

Direct3D-Direct2D interop sample (Windows 8) This sample shows how to interoperate with Direct2D and
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 (Windows 8) This sample demonstrates a basic Windows Store app for
Windows 8 that can retrieve feeds from a web service. This
sample is currently provided in the JavaScript, C#, C++, and
VB programming languages.
SA M P L E N A M E DESC RIP T IO N

App tiles and badges sample (Windows 8) This sample shows how to use an app tile, which is the
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 controls sample (Windows 8) This sample demonstrates how to create and use XAML
UserControl elements and create custom controls for your
projects.

Direct3D resource loading sample (Windows 8) This sample demonstrates Direct3D resource loading for
C++ apps with DirectX.

XAML ListView and GridView customizing interactivity This sample demonstrates the interaction model of the
sample (Windows 8) ListView control.

XAML WebView control sample (Windows 8) This sample demonstrates how to use the WebView control
to display a URL, load HTML, interact with script within a
WebView , and use WebViewBrush .

Compass sensor sample (Windows 8) This sample demonstrates how to use the
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 (Windows 8) This sample demonstrates how to use the
DisplayProperties class to set the display orientation in
an app.

Direct2D interpolation modes sample (Windows 8) This sample shows the various interpolation modes used by
Direct2D.

Globalization preferences sample (Windows 8) This sample demonstrates how to use the
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 realization sample (Windows 8) This sample shows how multi-core geometry tessellation can
help reduce geometry rendering time. Using opacity masks
and meshes is an alternative to traditional geometry
rendering that may be better in some situations.

Language font mapping sample (Windows 8) This sample demonstrates how to obtain language-specific
font recommendations using the LanguageFontGroup class
in the Windows.Globalization.Fonts namespace.

Inclinometer sensor sample (Windows 8) This sample shows how to use the
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.
SA M P L E N A M E DESC RIP T IO N

XAML high contrast style sample (Windows 8) This sample demonstrates various techniques for
implementing 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 sample (Windows 8) This sample demonstrates how to query the input devices
that are connected to the user's device. And, how to support
the pointer, touch, pen/stylus, mouse, and keyboard input
modes of Windows Store apps.

EAS policies for mail clients sample (Windows 8) This sample shows how mail clients can retrieved device
information 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 (Windows 8) This sample demonstrates the basics of the


DatagramSocket class 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 sample (Windows 8) This sample shows how to use DirectWrite and Direct2D to
render the text "Hello World" to a CoreWindow .

Compression sample (Windows 8) This sample demonstrates how to read structured data from
a file 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 background sample (Windows 8) This sample demonstrates how to determine a change in
Internet connection profile by registering a background task
handler for Network Status Change event using an Internet
Present condition.

App package information sample (Windows 8) This sample shows you how to get package information
using the 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 (Windows 8) This sample shows how to use the


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 provisioning sample (Windows 8) This sample demonstrates how to use the Windows 8
Mobile Broadband provisioning agent API (
Windows.Networking.NetworkOperators.ProvisioningAgent
) to configure Windows 8 with required connectivity
information and access provisioning.

Media Play To sample (Windows 8) This sample demonstrates the Play To API. It shows how you
can expand your media application to stream video, audio,
and images to other devices on your local network.
SA M P L E N A M E DESC RIP T IO N

Input Touch keyboard sample (Windows 8) This sample demonstrates how to launch the touch
keyboard 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.

XAML animation library sample (Windows 8) This sample demonstrates how to animate elements and
apply 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 (Windows 8) This sample demonstrates how to use the
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 transforms sample (Windows 8) This sample demonstrates how to use two-dimensional
transforms to modify how elements are displayed in your
app. A transform defines how to map, or transform, points
from one coordinate space to another coordinate space.

IXmlReader and IXmlWriter XML data read write sample This sample demonstrates how to use IXmlReader and
(Windows 8) IXmlWriter in your Windows Store app with C++. They're
used to read and 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 capture device sample (Windows 8) This sample demonstrates how to use the MediaCapture
API to capture video, audio, and pictures from a capture
device, such as a webcam.

XAML Popup sample (Windows 8) This sample demonstrates how to create and use the XAML
Popup element in your projects.

CameraCaptureUI Sample (Windows 8) This sample demonstrates how to use the


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 playback sample (Windows 8) This sample demonstrates the use of XAudio2 in an app.

Hilo C++ sample (Windows 8) This sample demonstrates how to build a complete Windows
Store 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 renderer sample (Windows 8) This sample shows how to implement a custom text renderer
for DirectWrite.
SA M P L E N A M E DESC RIP T IO N

DirectWrite font enumeration sample (Windows 8) This sample shows how to use DirectWrite to list the fonts in
the system font collection on a user's device.

Direct2D perspective transform sample (Windows 8) This sample shows how to use the DrawBitmap API to
display an image with a perspective transform applied to it.

CameraOptionsUI Sample (Windows 8) This sample demonstrates how to use camera options in a
device app. The CameraOptionsUI API displays a UI for
adjusting camera settings. This sample requires a webcam.

XInput audio controller playback sample (Windows 8) This sample demonstrates XAudio2 playback to an XInput
device, such as a headset, in an app.

Direct2D 3D transform effect sample (Windows 8) This sample demonstrates the different methods to
transform an image in 3-D space.

Windows account authorization sample (Windows 8) This sample demonstrates how to use the members of the
Windows.Security.Authentication.OnlineId namespace
to 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 parsing sample (Windows 8) This sample demonstrates how to use the
DecimalFormatter , CurrencyFormatter ,
PercentFormatter , and PermilleFormatter classes in
the Windows.Globalization.NumberFormatting
namespace. They're used to display and parse numbers,
currencies, and percent values.

DXGI offer and reclaim resources sample (Windows 8) This sample demonstrates the use of the DXGI
IDXGIDevice2::OfferResources and
IDXGIDevice2::ReclaimResources APIs in a C++ app with
DirectX.

Web authentication broker sample (Windows 8) This sample demonstrates the web authentication broker
WinRT API. It lets you enable single sign-on (SSO)
connections to OAuth providers such as Facebook, Google,
Microsoft, and Twitter.

XAudio2 audio stream effect sample (Windows 8) This sample demonstrates audio streaming in a C++ app
using the XAudio2 and Media Foundation APIs.

Splash screen sample (Windows 8) This sample shows how to imitate the splash screen that
Windows displays for your app, by positioning a similar
image correctly when Windows dismisses the splash screen
that it displays.

SMS background task sample (Windows 8) This sample shows how to use the Windows 8 Mobile
Broadband SMS API ( Windows.Devices.Sms ) with the
Background Task API (
Windows.ApplicationModel.Background ) to send and
receive SMS text messages.

SMS message send, receive, and SIM management sample This sample shows how to use the Windows 8 Mobile
(Windows 8) Broadband SMS API ( Windows.Devices.Sms ).
SA M P L E N A M E DESC RIP T IO N

Trial app and in-app purchase sample (Windows 8) This sample demonstrates how to use the licensing API
provided by the Windows Store to determine the license
status of an app, or of a feature enabled by an in-app
purchase.

Input Touch keyboard text input sample (Windows 8) This sample shows how to enable optimized views on the
touch 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 (Windows 8) This sample demonstrates how to use text input controls in
your app.

Thread pool sample (Windows 8) This sample shows you how to run work items
asynchronously using the Windows Runtime thread pool
API.

UI Automation core window provider sample (Windows 8) This sample demonstrates how to create a Microsoft UI
Automation provider. It makes programmatic information
about a Windows Store app available to accessible
technologies such as screen readers. The sample is a
Direct2D application.

XAML accessibility sample (Windows 8) This sample shows you how to add basic accessibility
support to your app.

Playlist sample (Windows 8) This sample demonstrates how to create, save, display, and
edit a playlist of audio files. This sample uses classes that are
in the Windows.Media.Playlists namespace.

Media Server client sample (Windows 8) This sample demonstrates how to create a Media Server
client using 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 sample (Windows 8) This sample shows how to use Direct2D, DirectWrite,
Windows Imaging Component (WIC), and XAML to build an
app with a magazine-type presentation.

Mobile broadband account and device management sample This sample shows how to use the Windows 8 Mobile
(Windows 8) Broadband API ( Windows.Networking.NetworkOperators )
employed by Mobile Network Operators (MNO). It
demonstrates how to use the MobileBroadbandAccount
APIs to retrieve and display available Mobile Broadband
accounts.

Proximity sample (Windows 8) This sample demonstrates how to use the PeerFinder and
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.
SA M P L E N A M E DESC RIP T IO N

Creating a Windows Runtime in-process component sample This sample shows how to create a component in C++/CX
(C++CX) (Windows 8) that's used in C++/CX, JavaScript, and C# client code. The
OvenServer project contains a runtime class named Oven ,
which implements an IOven interface and an IAppliance
interface.

Device auto rotation preferences sample (Windows 8) This sample shows how to use the DisplayProperties
class to handle and verify device rotation events.

Real-time communication sample (Windows 8) This sample demonstrates how to use the low latency
feature to enable real-time communication applications.

Sharing content source app sample (Windows 8) This sample demonstrates how an app can share content
with another app. This sample uses classes from the
Windows.ApplicationModel.DataTransfer namespace.

Search contract sample (Windows 8) This sample shows how to let users search your app when
they 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 (Windows 8) This sample shows how to use raw notifications, which are
push notifications with no associated UI that perform a
background task for the app.

Direct2D basic image effects sample (Windows 8) This sample shows how to load an image, apply the
Gaussian blur effect to it, and then display it in a
Windows::UI::Core::CoreWindow .

Direct2D effects on primitives sample (Windows 8) This sample shows how to apply image effects to Direct2D
primitives. This sample draws rounded rectangles using
Direct2D and then draws DirectWrite text in the middle of
the rectangles. Then it applies an effect graph to it.

ControlChannelTrigger StreamSocket sample (Windows 8) The sample shows how to use the ControlChannelTrigger
class in a Windows Store app. It uses a TCP StreamSocket ,
so the app is always connected and always reachable. This
sample demonstrates the use of background network
notifications.

ControlChannelTrigger StreamWebSocket sample (Windows The sample shows how to use the ControlChannelTrigger
8) class to enable a Windows Store app using a
StreamWebSocket to be always connected and always
reachable. This sample demonstrates the use of background
network notifications.

Association launching sample (Windows 8) This sample shows you how to launch the user's default app
for file 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.

AtomPub sample (Windows 8) This sample demonstrates how to access, create, update, and
remove syndicated content feeds from the web. It uses the
Windows Runtime implementation of the Atom Publication
standard.
SA M P L E N A M E DESC RIP T IO N

Certificate enrollment sample (Windows 8) This sample demonstrates how to create and enroll a
certificate in a 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 (Windows 8) This sample demonstrates how an app can use clipboard
commands, including copy, paste, cut, and move. This
sample uses classes from the
Windows.ApplicationModel.DataTransfer namespace.

Direct2D composite effect modes sample (Windows 8) This sample shows the wide range of composite and blend
modes available from Direct2D.

Direct3D bump mapping sample (Windows 8) This sample demonstrates bump mapping using a normal
map and per-pixel lighting.

Calendar details and math sample (Windows 8) This sample demonstrates how to use the Calendar class
in the Windows.Globalization namespace to manipulate
and process dates based on a calendar system and the user's
globalization preferences.

Device enumeration sample (Windows 8) This sample shows how to use the Device Enumeration API
to find 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 sample (Windows 8) This sample shows how to use DirectWrite and Direct2D to
render paragraph text to a CoreWindow . And, apply
justification and character spacing to the layout.

Responding to the appearance of the on-screen keyboard [This documentation is preliminary and is subject to change.]
sample (Windows 8) This sample shows how to listen for and respond to the
appearance of the onscreen soft keyboard. When focus is
given to an element that requires text input on a device that
doesn't have a keyboard.

XAML data binding sample (Windows 8) This sample demonstrates basic data binding techniques
using the Binding class and Binding markup extension.

Direct3D tutorial sample (Windows 8) This sample is a five-lesson tutorial. It provides an


introduction to the Direct3D API, and introduces the
concepts and code used in many of the other DirectX
samples.

Direct2D effects photo adjustment app sample (Windows 8) This sample shows various common photo manipulation
techniques using Direct2D Effects. This sample is divided into
several parts. Lesson 1: Shows the basics of loading and
drawing an image using Direct2D Effects.

Windows Audio Session (WASAPI) sample (Windows 8) Demonstrates how to do various audio related tasks using
the Windows Audio Session API (WASAPI).
SA M P L E N A M E DESC RIP T IO N

User domain name sample (Windows 8) This sample demonstrates the domain-related functionality
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 management sample (Windows 8) This sample demonstrates network account management
using the USSD protocol with GSM-capable mobile
broadband devices. USSD is typically used for account
management of a mobile broadband profile by the Mobile
Network Operator (MNO).

Bing Maps Trip Optimizer sample (Windows 8) The sample demonstrates how to use JavaScript and Visual
C++ 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 animated text on a path sample This sample shows how to use Direct2D and DirectWrite to
(Windows 8) render a string of text along an animated, non-linear
geometric path. The app renders "Hello, World!" repeated
several times in different languages along a Bezier curve.

Wi-Fi hotspot authentication sample (Windows 8) This sample demonstrates how to use the Windows 8
Mobile Broadband API (
Windows.Networking.NetworkOperators ) for Wi-Fi hotspot
authentication. Use this mechanism as an alternative to
configuring static credentials for a Wi-Fi hotspot.

XAML images sample (Windows 8) This sample demonstrates various techniques for displaying
and manipulating images in your app using the Image
control and the BitmapImage class.

HomeGroup app sample (Windows 8) This sample demonstrates how to use a HomeGroup to
open, search, 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 sample (Windows 8) This sample shows how to use the UI settings APIs in a basic
C# or JavaScript app.

Folder enumeration sample (Windows 8) This sample shows how to list the top-level files and folders
inside a 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.

File picker sample (Windows 8) This sample shows how to access files and folders by letting
the 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.
SA M P L E N A M E DESC RIP T IO N

File picker contracts sample (Windows 8) This sample shows how an app can provide files, a save
location, 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 sample (Windows 8) This sample shows how to query files in locations such as a
folder, 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 sample (Windows 8) This sample shows how to retrieve thumbnails for files and
folders. It uses Windows.Storage.FileProperties API.

Input Manipulations and gestures (C++) sample (Windows This sample demonstrates how to handle pointer input and
8) process manipulations and gestures with the
GestureRecognizer APIs in a Windows Store app using
C++ and DirectX.

Direct3D HLSL fractal generator sample (Windows 8) This sample demonstrates the use of Direct3D HLSL and
DirectCompute compute shaders to create fractal images.

XAML Direct2D lighting effects sample (Windows 8) This sample demonstrates the lighting effects available in
Direct2D Effects. The lighting effect properties are controlled
by XAML interface controls and then displayed using
Direct2D via a XAML SwapChainBackgroundPanel.

Direct2Dapp printing sample (Windows 8) This sample demonstrates how to add Direct2D printing
support to 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 and effects sample (Windows 8) This sample demonstrates how to print Direct2D images and
Direct2D effects in a Windows Store app.

Direct2D animated text sample (Windows 8) This sample shows how to render text quickly by using the
Direct2D 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 effects sample (Windows 8) This sample demonstrates Direct3D 11.1 post-processing on
a simple rotating cube scene, using down-scaled
intermediate buffers.

Extended Linguistic Services (ELS) sample (Windows 8) This sample demonstrates the use of Extended Linguistic
Services (ELS) in a Windows Store app. The sample
implements scenarios that demonstrate the use of the three
available ELS services. The scenarios demonstrate how to
request a specific service.

DirectWrite hit testing sample (Windows 8) This sample shows how to use the hit-testing features of
DirectWrite. They're used to determine which part of the
displayed text is being clicked or touched.
SA M P L E N A M E DESC RIP T IO N

DirectWrite inline object sample (Windows 8) This sample shows how to insert an inline object into a text
layout, such as an image.

XAML vector-based drawing sample (Windows 8) This sample demonstrates how to draw vector-based
graphics in your app.

Bluetooth call control sample (Windows 8) The Bluetooth CallControl sample demonstrates how to
configure 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 sample (Windows 8) This sample demonstrates the use of a command list. It's
used for 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 XMLHTTPRequest sample (Windows The sample shows how to use the ControlChannelTrigger
8) class to enable a Windows Store app using
IXMLHTTPRequest2 to be always connected and always
reachable. This sample demonstrates the use of background
network notifications in a Windows Store app.

XInput and JavaScript controller sketch sample (Windows 8) This sample demonstrates how to wrap the XInput C++ API
in a Windows Runtime component. Then, it calls it from a
Windows 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 effect sample (Windows 8) This sample demonstrates the Direct2D Effects convolve
matrix 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 implementation sample (Windows 8) This sample shows how to receive CoreWindow events in a
native application, and how to connect a DirectX swap chain
to the application view.

Credential picker sample (Windows 8) This sample shows how to use the
Windows.Security.Credentials.UI.CredentialPicker
class to retrieve credentials. These credentials may be passed
to APIs that require them, for example, HttpClient .

Direct2D animation sample (Windows 8) This sample shows how to use Direct2D to render and
animate a Direct2D primitive along a spiral path.

Sharing content target app sample (Windows 8) This sample demonstrates how an app can receive content
shared from another app. This sample uses classes from the
Windows.ApplicationModel.DataTransfer and
Windows.ApplicationModel.DataTransfer.Share
namespaces.
SA M P L E N A M E DESC RIP T IO N

Direct2D save to image file sample (Windows 8) This sample shows how to render to the screen using
Direct2D and DirectWrite. And, how to save the rendered
image to disk using the WIC API.

Scaling according to DPI sample (Windows 8) This sample describes how to build an app that scales
according to 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 Runtime in-process component sample This sample shows how to create a component in C# that's
(C#) (Windows 8) used in C++/CX, JavaScript, and C# client code. The
OvenServer project contains a runtime class named Oven ,
which implements an IOven interface and an IAppliance
interface.

Push and periodic notifications client-side sample (Windows This sample shows how a client app can register and listen
8) for push notifications sent from a web server. Push
notifications can be used to update a badge or a tile, raise a
toast notification, or launch a background task.

Portable device API sample (Windows 8) This sample shows how to access the IPortableDevice
COM API 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 (Windows 8) This sample demonstrates how to create a software Play To
receiver. To advertise the software Play To Receiver, click the
Start Receiver button. To stop the receiver, click the Stop
Receiver button.

Lock screen personalization sample (Windows 8) This sample demonstrates how to use the LockScreen API
to set the current user's lock screen image. This sample uses
classes from the Windows.System.UserProfile namespace.

Credential locker sample (Windows 8) This sample demonstrates how to use the WinRT
PasswordVault 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.

Media engine native C++ video playback sample (Windows This sample demonstrates video playback using the
8) MediaEngine API in a native C++ app.

Media extensions sample (Windows 8) This sample demonstrates how to use media extensions. You
can apply effects to video, decode video, and create media
streams using scheme handlers.

Lock screen apps sample (Windows 8) This sample shows how an app can have a presence on the
lock 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 (Windows 8) This sample demonstrates how control the appearance of
text in your app.
SA M P L E N A M E DESC RIP T IO N

SimpleOrientationSensor sample (Windows 8) This sample shows how to use the


Windows.Devices.Sensors.SimpleOrientationSensor API.

Direct3D sprite sample (Windows 8) This sample provides a Direct3D implementation of sprite
batch 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 sample (Windows 8) This sample demonstrates how to add a stereoscopic 3-D
effect to 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 Runtime DLL component with C++ This sample shows how to create an in-process DLL
sample (Windows 8) component in Microsoft Visual C++. It's used in C++/CX,
JavaScript, and C# client code. The OvenServer project
contains a runtime class named Oven , which implements an
IOven interface.

Creating a Windows Runtime EXE component with C++ This sample shows how to create an out-of-process EXE
sample (Windows 8) component in Microsoft Visual C++. It's used in C++/CX,
JavaScript, and C# client code. The OvenServer project
contains a runtime class named Oven , which implements an
IOven interface.
Microsoft C/C++ help and community
3/6/2021 • 2 minutes to read • Edit Online

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 10.
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 are
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 docs.microsoft.com.

Related sites
C++ Team Blog: Contains posts on various subjects by the experts on Microsoft's C++ product team.
Channel 9: Contains video interviews and lectures. Use the search box on the Channel 9 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 Docs 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
3/6/2021 • 25 minutes to read • Edit Online

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've 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 sections below, you'll read about what makes a good report. We describe how to generate a repro for the
kind of issue you've 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:
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.dll: 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.dll: 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've 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.command.1.tlog, or in
your User folder under
\Source\Repos\SolutionName\ProjectName\Configuration\ProjectName.tlog\CL.command.1.tlog. It may
be in a different location if you use another build system, or if you've changed the default location for
your project.
Inside this file, you'll 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've 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've 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, you'll 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've
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've
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've 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 have often been 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've 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.

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:

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.

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 will emit Linker
Tools Error LNK1000.

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:

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've 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 you'll 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 additional source and header files. The option also resolves
macros, #ifdef conditionals, and other preprocessor commands that could depend on your local environment.

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 additional
steps are required. For more information, see the sections below.
After you've generated 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've generated 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 has 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
Proper ty Pages dialog for your project. Select the Configuration Proper ties > 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 Report a Problem
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.

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 Repor t 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've found. You can then
submit your report without ever leaving the IDE.
Reporting your problem through the Repor t 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 > Repor t 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 additional specifics. If you don't
see a similar problem, choose the Repor t 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'll 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 hasn't been reported before, choose the Repor t 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
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 Repor t 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've 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 repor ts 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 repor t, 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 much 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'll 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 A New Feedback System Is Coming to
docs.microsoft.com.
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.
Install C and C++ support in Visual Studio
9/21/2021 • 8 minutes to read • Edit Online

If you haven't downloaded and installed Visual Studio and the Microsoft C/C++ tools yet, here's how to get
started.

Visual Studio 2019 Installation


Welcome to Visual Studio 2019! 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.

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 2019.
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 2019, see the
Visual Studio 2019 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.
D O W NLO AD VISU AL
S TU D IO

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!

Visual Studio 2017 Installation


In Visual Studio 2017, 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.
Prerequisites
A broadband internet connection. The Visual Studio installer can download several gigabytes of data.
A computer that runs Microsoft Windows 7 or later versions. We recommend Windows 10 for the best
development experience. Make sure that the latest updates are applied to your system before you install
Visual Studio.
Enough free disk space. Visual Studio requires at least 7 GB of disk space, and can take 50 GB or more if
many common options are installed. We recommend you install it on your C: drive.
For details on the disk space and operating system requirements, see Visual Studio Product Family System
Requirements. The installer reports how much disk space is required for the options you select.
Download and install
1. To download the latest Visual Studio 2017 installer for Windows, go to the Microsoft Visual Studio Older
downloads page. Expand the 2017 section, and choose the Download button.

TIP
The Community edition is for individual developers, classroom learning, academic research, and open source
development. For other uses, install Visual Studio 2017 Professional or Visual Studio 2017 Enterprise.

2. Find the installer file you downloaded and run it. The downloaded file may be displayed in your browser,
or you may find it in your Downloads folder. The installer needs Administrator privileges to run. You may
see a User Account Control dialog asking you to give permission to let the installer make changes to
your system; choose Yes . If you're having trouble, find the downloaded file in File Explorer, right-click on
the installer icon, and choose Run as Administrator from the context menu.

3. The installer presents you with a list of workloads, which are groups of related options for specific
development areas. Support for C++ is now part of optional workloads that aren't installed by default.

For C and C++, select the Desktop development with C++ workload and then choose Install .
4. When the installation completes, choose the Launch button to start Visual Studio.
The first time you run Visual Studio, you're asked to sign in with a Microsoft Account. If you don't have
one, you can create one for free. You must also choose a theme. Don't worry, you can change it later if
you want to.
It may take Visual Studio several minutes to get ready for use the first time you run it. Here's what it looks
like in a quick time-lapse:
Visual Studio starts much faster when you run it again.
5. When Visual Studio opens, check to see if the flag icon in the title bar is highlighted:
If it's highlighted, select it to open the Notifications window. If there are any updates available for Visual
Studio, we recommend you install them now. Once the installation is complete, restart Visual Studio.

Visual Studio 2015 Installation


To install Visual Studio 2015, go to the Microsoft Visual Studio Older downloads page. Expand the 2015 section,
and choose the Download button. Run the downloaded setup program and choose Custom installation and
then choose the C++ component. To add C and C++ support to an existing Visual Studio 2015 installation, click
on the Windows Start button and type Add Remove Programs . Open the program from the results list and
then find your Visual Studio 2015 installation in the list of installed programs. Double-click it, then choose
Modify and select the Visual C++ components to install.
In general, we highly recommend that you use the latest version of Visual Studio even if you need to compile
your code using the Visual Studio 2015 compiler. For more information, see Use native multi-targeting in Visual
Studio to build old projects.
When Visual Studio is running, you're ready to continue to the next step.

Next Steps
Create a C++ project
https://docs.microsoft.com/
Create a C++ console app project
7/28/2021 • 6 minutes to read • Edit Online

The usual starting point for a C++ programmer is a "Hello, world!" application that runs on the command line.
That's what you'll 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, you'll 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 fills in your source code with a "Hello World" app:

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.
1. In Visual Studio, open the File menu and choose New > Project to open the New Project dialog.
2. In the New Project dialog, select Installed > Visual C++ if it isn't selected already, and then choose
the Empty Project template. In the Name field, enter HelloWorld. Choose OK to create the project.

Visual Studio creates a new, empty project. It's ready for you to specialize for the kind of app you want to create
and to add your source code files. You'll do that next.
I ran into a problem.

Make your project a console app


Visual Studio can create all kinds of apps and components for Windows and other platforms. The Empty
Project template isn't specific about what kind of app it creates. A console app is one that runs in a console or
command prompt window. To create one, you must tell Visual Studio to build your app to use the console
subsystem.
1. In Visual Studio, open the Project menu and choose Proper ties to open the HelloWorld Proper ty
Pages dialog.
2. In the Proper ty Pages dialog, select Configuration Proper ties > Linker > System , and then choose
the edit box next to the Subsystem property. In the dropdown menu that appears, select Console
(/SUBSYSTEM:CONSOLE) . Choose OK to save your changes.

Visual Studio now knows to build your project to run in a console window. Next, you'll add a source code file and
enter the code for your app.
I ran into a problem.

Add a source code file


1. In Solution Explorer , select the HelloWorld project. On the menu bar, choose Project , Add New Item
to open the Add New Item dialog.
2. In the Add New Item dialog, select Visual C++ under Installed if it isn't selected already. In the center
pane, select C++ file (.cpp) . Change the Name to HelloWorld.cpp. Choose Add to close the dialog and
create the file.
Visual studio creates a new, empty source code file and opens it in an editor window, ready to enter your source
code.
I ran into a problem.

Add code to the source file


1. Copy this code into the HelloWorld.cpp editor window.

#include <iostream>

int main()
{
std::cout << "Hello, world!" << std::endl;
return 0;
}

The code should look like this in the editor window:

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.
If the New Project dialog doesn't show a Visual C++ entry under Installed , your copy of Visual Studio
probably doesn't have the Desktop development with C++ workload installed. You can run the installer right
from the New Project dialog. Choose the Open Visual Studio Installer link to start the installer again. If the
User Account Control dialog requests permissions, choose Yes . Update the installer if necessary. In the
installer, make sure the Desktop development with C++ workload is checked, and choose OK 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.
Make your project a console app: issues
If you don't see Linker listed under Configuration Proper ties , choose Cancel to close the Proper ty Pages
dialog. Make sure that the HelloWorld project is selected in Solution Explorer before you try again. Don't
select the HelloWorld solution, or another item, in Solution Explorer .
The dropdown control doesn't appear in the SubSystem property edit box until you select the property. Click in
the edit box to select it. Or, you can press Tab to cycle through the dialog controls until SubSystem is
highlighted. Choose the dropdown control or press Alt+Down to open it.
Go back
Add a source code file: issues
It's okay if you give the source code file a different name. However, don't add more than one file that contains
the same code to your project.
If you added the wrong file type to your project, such as a header file, delete it and try again. To delete the file,
select it in Solution Explorer . Then press the Delete key.
Go back.
Add code to the source file: issues
If you accidentally closed the source code file editor window, you can easily open it again. To open it, double-
click on HelloWorld.cpp in the Solution Explorer window.
If red squiggles appear under anything in the source code editor, check that your code matches the example in
spelling, punctuation, and case. Case is significant in C++ code.
Go back.
https://docs.microsoft.com/
Build and run a C++ console app project
7/28/2021 • 3 minutes to read • Edit Online

You've 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 yet, follow the steps in Install C++ support in Visual Studio.
Create a "Hello, World!" project and enter its source code. 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, choose 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, choose Debug , Star t 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've 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 your app is built by Visual
Studio, you can run it from any 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 Debug folder. This folder contains your app, HelloWorld.exe, and a
couple of other 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.
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've built and run a console app in Visual Studio!


I ran into a problem.

Next Steps
Once you've built 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've opened the HelloWorld project
instead of the HelloWorld solution. You'll be confused by a Debug folder that doesn't contain your app. Navigate
up a level in File Explorer to get to the solution folder, the first HelloWorld in the path. This folder also contains a
Debug folder, and you'll find your app there.
You can also navigate to the solution 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.
https://docs.microsoft.com/
Create a console calculator in C++
9/2/2021 • 39 minutes to read • Edit Online

The usual starting point for a C++ programmer is a "Hello, world!" application that runs on the command line.
That's what you'll create first in Visual Studio in this article, and then we'll move on to something more
challenging: a calculator app.

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 also manages the relationship
between all the project's files and any external files. To create your app, first, you'll create a new project and
solution.
1. If you've just started Visual Studio, you'll see the Visual Studio 2019 dialog box. Choose Create a new
project to get started.

Otherwise, on the menubar in Visual Studio, choose File > New > Project . The Create a new project
window opens.
2. In the list of project templates, choose Console App , then choose Next .
IMPORTANT
Make sure you choose 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 edit box, name your new
project CalculatorTutorial, then choose Create .

An empty C++ Windows console application gets 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:

// 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, choose 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, choose Debug , Star t 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 close this window . . ." to give you a chance to see the output.
Congratulations! You've 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'll show you how to debug it if it doesn't.

Edit the code


Now let's turn the code in this template into a calculator app.
1. In the CalculatorTutorial.cpp file, edit the code to match this example:

// 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 a 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 is a
better practice to put a \n inside the string (contained by "") to do the same thing, as endl
always flushes the buffer and 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, enter Ctrl+S , or choose 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 choose Star t 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


It's time to add some math logic.
To add a Calculator class
1. Go to the Project menu and choose Add Class . In the Class Name edit box, enter Calculator. Choose
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.
A class is like a blueprint for an object that does something. In this case, we define a calculator and how it
should work. The Add Class wizard you used above created .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: choose View > Solution
Explorer .

You should now have three tabs open in the editor: CalculatorTutorial.cpp, Calculator.h, and Calculator.cpp.
If you accidentally close one of them, you can reopen it by double-clicking it in the Solution Explorer
window.
2. In Calculator.h , remove the Calculator(); and ~Calculator(); lines that were generated, since you
won't need them here. Next, add the following line of code so the file now looks like this:

#pragma once
class Calculator
{
public:
double Calculate(double x, char oper, double y);
};
Understanding the code
The line you added declares a new function called Calculate , which we'll 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.
The two lines you deleted declared a constructor and destructor for the class. For a simple class
like this one, the compiler creates them for you, and their uses are beyond the scope of this
tutorial.
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. You'll see a green squiggle appear under Calculate . It's because we haven't defined the Calculate
function in the .cpp file. Hover over the word, click the lightbulb (in this case, a screwdriver) that pops up,
and choose Create definition of 'Calculate' in Calculator.cpp .

A pop-up appears that gives you a peek of the code change that was made in the other file. The code was
added to Calculator.cpp.
Currently, it just returns 0.0. Let's change that. Press Esc to close the pop-up.
4. Switch to the Calculator.cpp file in the editor window. Remove the Calculator() and ~Calculator()
sections (as you did in the .h file) and add the following code to Calculate() :

#include "Calculator.h"

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 still exit after asking which operation to perform. Next,
you'll modify the main function to do some calculations.
To call the Calculator class member functions
1. Now let's update the main function in CalculatorTutorial.cpp:

// 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 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 is 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, for instance, 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 it's time to 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 some
input as expected. Instead of running the program, let's debug it instead, so we can inspect what it's doing in
detail, step-by-step.
To run the app in the debugger
1. Set a breakpoint on the result = c.Calculate(x, oper, y); line, just after the user was asked for input. 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, it always pauses execution 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, let's make
the breakpoint conditional.
2. Right-click the red dot that represents the breakpoint, and choose Conditions . In the edit box for the
condition, enter (y == 0) && (oper == '/') . Choose the Close button when you're done. The condition is
saved automatically.

Now we pause execution at the breakpoint specifically if a division by 0 is attempted.


3. To debug the program, press F5 , or choose 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 even put any
number of spaces between the operator and numbers: cin is smart enough to parse the input
appropriately.
Useful windows in the debugger
Whenever 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 actually modify the values of these variables while debugging, to
see what effect they would have on the program. In this case, we'll leave them alone.

You can also just hover over variables in the code itself to see their current values where the execution is
currently paused. Make sure the editor window is in focus by clicking on it first.

To continue debugging
1. The yellow line on the left shows the current point of execution. The current line calls Calculate , so press
F11 to Step Into the function. You'll find yourself in the body of the Calculate function. Be careful with
Step Into ; if you do it too much, you may waste a lot of time. It goes into any code you use on the line
you are on, including standard library functions.
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.
It looks like the program is doing what is 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. You'll
see its value is listed as "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 happens because division by zero is undefined, so the program doesn't have a numerical
answer to the requested operation.
To fix the "divide by zero" error
Let's handle division by zero more gracefully, so a user can 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 ):
// 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 << "Division by 0 exception" << endl;
continue;
}
else
{
result = c.Calculate(x, oper, y);
}
cout << "Result is: " << result << endl;
}

return 0;
}

2. Now 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.
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 pops up 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'll need to step out of the function, then back into it again to get the updated code. If that doesn't work for
some reason 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.

Understanding the Run and Debug shortcuts


F5 (or Debug > Star t 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 enter F5 to keep the window open.
Ctrl+F5 (or Debug > Star t 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 repositor y 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, you see status details 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've 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++
The usual starting point for a C++ programmer is a "Hello, world!" application that runs on the command line.
That's what you'll create in Visual Studio in this article, and then we'll move on to something more challenging: a
calculator app.

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 also manages the relationship
between all the project's files and any external files. To create your app, first, you'll create a new project and
solution.
1. On the menubar in Visual Studio, choose File > New > Project . The New Project window opens.
2. On the left sidebar, make sure Visual C++ is selected. In the center, choose Windows Console
Application .
3. In the Name edit box at the bottom, name the new project CalculatorTutorial, then choose OK .
An empty C++ Windows console application gets 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:

// CalculatorTutorial.cpp : This file contains the 'main' function. Program execution begins and ends
there.
//

#include "pch.h"
#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, choose 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, choose Debug , Star t 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've 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'll show you how to debug it if it doesn't.

Edit the code


Now let's turn the code in this template into a calculator app.
1. In the CalculatorTutorial.cpp file, edit the code to match this example:

// CalculatorTutorial.cpp : This file contains the 'main' function. Program execution begins and ends
there.
//

#include "pch.h"
#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 #include "pch.h" (or in Visual Studio 2017 and earlier, #include "stdafx.h" ) line references
something known as a precompiled header. These are often used by professional programmers to
improve compilation times, but they are beyond the scope of this tutorial.
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 a 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 is a
better practice to put a \n inside the string (contained by "") to do the same thing, as endl
always flushes the buffer and 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, enter Ctrl+S , or choose 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 choose Star t Without Debugging .
If you get a pop-up that says This project is out of date , you may select Do not show this dialog
again , and then choose Yes to build your application. 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
It's time to add some math logic.
To add a Calculator class
1. Go to the Project menu and choose Add Class . In the Class Name edit box, enter Calculator. Choose
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.

A class is like a blueprint for an object that does something. In this case, we define a calculator and how it
should work. The Add Class wizard you used above created .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: choose View > Solution
Explorer .

You should now have three tabs open in the editor: CalculatorTutorial.cpp, Calculator.h, and Calculator.cpp.
If you accidentally close one of them, you can reopen it by double-clicking it in the Solution Explorer
window.
2. In Calculator.h , remove the Calculator(); and ~Calculator(); lines that were generated, since you
won't need them here. Next, add the following line of code so the file now looks like this:
#pragma once
class Calculator
{
public:
double Calculate(double x, char oper, double y);
};

Understanding the code


The line you added declares a new function called Calculate , which we'll 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.
The two lines you deleted declared a constructor and destructor for the class. For a simple class
like this one, the compiler creates them for you, and their uses are beyond the scope of this
tutorial.
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. You'll see a green squiggle appear under Calculate . It's because we haven't defined the Calculate
function in the .cpp file. Hover over the word, click the lightbulb that pops up, and choose Create
definition of 'Calculate' in Calculator.cpp . A pop-up appears that gives you a peek of the code
change that was made in the other file. The code was added to Calculator.cpp.

Currently, it just returns 0.0. Let's change that. Press Esc to close the pop-up.
4. Switch to the Calculator.cpp file in the editor window. Remove the Calculator() and ~Calculator()
sections (as you did in the .h file) and add the following code to Calculate() :
#include "pch.h"
#include "Calculator.h"

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 still exit after asking which operation to perform. Next,
you'll modify the main function to do some calculations.
To call the Calculator class member functions
1. Now let's update the main function in CalculatorTutorial.cpp:
// CalculatorTutorial.cpp : This file contains the 'main' function. Program execution begins and ends
there.
//

#include "pch.h"
#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 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 is 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, for instance, 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 it's time to 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 some
input as expected. Instead of running the program, let's debug it instead, so we can inspect what it's doing in
detail, step-by-step.
To run the app in the debugger
1. Set a breakpoint on the result = c.Calculate(x, oper, y); line, just after the user was asked for input. 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, it always pauses execution 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, let's make
the breakpoint conditional.
2. Right-click the red dot that represents the breakpoint, and choose Conditions . In the edit box for the
condition, enter (y == 0) && (oper == '/') . Choose the Close button when you're done. The condition is
saved automatically.

Now we pause execution at the breakpoint specifically if a division by 0 is attempted.


3. To debug the program, press F5 , or choose 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 even put any
number of spaces between the operator and numbers; cin is smart enough to parse the input
appropriately.

Useful windows in the debugger


Whenever 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 actually modify the values of
these variables while debugging, to see what effect they would have on the program. In this case, we'll leave
them alone.

You can also just hover over variables in the code itself to see their current values where the execution is
currently paused. Make sure the editor window is in focus by clicking on it first.

To continue debugging
1. The yellow line on the left shows the current point of execution. The current line calls Calculate , so press
F11 to Step Into the function. You'll find yourself in the body of the Calculate function. Be careful with
Step Into ; if you do it too much, you may waste a lot of time. It goes into any code you use on the line
you are on, including standard library functions.
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.
It looks like the program is doing what is 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. You'll
see its value is listed as "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 happens because division by zero is undefined, so the program doesn't have a numerical
answer to the requested operation.
To fix the "divide by zero" error
Let's handle division by zero more gracefully, so a user can 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 ):
// CalculatorTutorial.cpp : This file contains the 'main' function. Program execution begins and ends
there.
//

#include "pch.h"
#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 << "Division by 0 exception" << endl;
continue;
}
else
{
result = c.Calculate(x, oper, y);
}
cout << "Result is: " << result << endl;
}

return 0;
}

2. Now 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.
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 pops up 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'll need to step out of the function, then back into it again to get the updated code. If that doesn't work for
some reason 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.

Understanding the Run and Debug shortcuts


F5 (or Debug > Star t 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 enter F5 to keep the window open.
Ctrl+F5 (or Debug > Star t 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.
Congratulations! You've completed the code for the calculator app, and built and debugged it in Visual Studio.

Next steps
Learn more about Visual Studio for C++
C/C++ projects and build systems in Visual Studio
9/21/2021 • 4 minutes to read • Edit Online

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
toolset as a free standalone package from Build Tools for Visual Studio 2019 download.
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:

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
7/28/2021 • 3 minutes to read • Edit Online

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 are 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 is 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.
If there is 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 are
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 docs.microsoft.com. 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++
Overview of Windows Programming in C++
5/10/2021 • 7 minutes to read • Edit Online

There are several broad categories of Windows applications that you can create with C++. Each has its own
programming model and set of Windows-specific libraries, but the C++ standard library and third-party C++
libraries can be used in any of them.
This section discusses how to use Visual Studio and the MFC/ATL wrapper libraries to create Windows
programs. For documentation on the Windows platform itself, see Windows documentation.

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++.

Native desktop client applications


A native desktop client application is a C or C++ windowed application that uses the original native Windows C
APIs or Component Object Model (COM) APIs to access the operating system. Those APIs are themselves written
mostly in C. There's more than one way to create a native desktop app: You can program using the Win32 APIs
directly, using a C-style message loop that processes operating system events. Or, you can program using
Microsoft Foundation Classes (MFC), a lightly object-oriented C++ library that wraps Win32. Neither approach
is considered "modern" compared to the Universal Windows Platform (UWP), but both are still fully supported
and have millions of lines of code running in the world today. A Win32 application that runs in a window
requires the developer to work explicitly with 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++. After you
gain some understanding of Win32, it will be easier to learn about MFC Desktop Applications. For an example of
a traditional C++ desktop application that uses sophisticated graphics, see Hilo: Developing C++ Applications
for Windows.
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.

COM Components
The Component Object Model (COM) is a specification that enables programs written in different languages to
communicate 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.

Universal Windows Platform apps


The Universal Windows Platform (UWP) is the modern Windows API. UWP apps run on any Windows 10 device,
use XAML for the user-interface, and are fully touch-enabled. 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 (1) C++/CX, a dialect of C++ with syntax extensions, or (2) the
Windows Runtime Library (WRL), which is based on standard C++ and COM. Both C++/CX and WRL are still
supported. For new projects, we recommend C++/WinRT, which is entirely based on standard C++ and
provides faster performance.

Desktop Bridge
In Windows 10, you can package your existing desktop application or COM object as a UWP app, and add 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, and 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.

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.

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 include folders that contain header files for these libraries are located in the Visual Studio
installation directory under the \VC\ folder. The Windows and CRT header files are found in the Windows SDK
installation folder.
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 the Windows 10 version of the Windows SDK. For information, see Windows 10
SDK. (For more information about the Windows SDKs for earlier versions of Windows, see the Windows SDK
archive).
Program Files (x86)\Windows Kits is the default location for all versions of the Windows SDK that you've
installed.
Other platforms such as Xbox and Azure have their own SDKs that you may have to install. For more
information, see the DirectX Developer Center and the Azure Developer Center.

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
T IT L E DESC RIP T IO N

Walkthrough: Creating a Standard C++ Program Create a Windows console application.

Walkthrough: Creating Windows Desktop Applications (C++) Create a native Windows desktop application.

Windows Desktop Wizard Use the wizard to create new Windows projects.

Active Template Library (ATL) Use the ATL library to create COM components in C++.

Microsoft Foundation Classes (MFC) Use MFC to create large or small Windows applications with
dialogs and controls

ATL and MFC Shared Classes Use classes such as CString that are shared in ATL and MFC.
T IT L E DESC RIP T IO N

Data Access OLE DB and ODBC

Text and Strings Various string types on Windows.

Resources for Creating a Game Using DirectX

How to: Use the Windows 10 SDK in a Windows Desktop Windows SDK
Application

Working with Resource Files How to add images, icons, string tables, and other resources
to a desktop application.

Resources for Creating a Game Using DirectX (C++) Links to content for creating games in C++.

How to: Use the Windows 10 SDK in a Windows Desktop Contains steps for setting up your project to build using the
Application Windows 10 SDK.

Deploying Native Desktop Applications Deploy native applications on Windows.

Related Articles
T IT L E DESC RIP T IO N

C++ in Visual Studio Parent topic for Visual C++ developer content.

.NET Development with C++/CLI Create wrappers for native C++ libraries that enable it to
communication with .NET applications and components.

Component Extensions for .NET and UWP Reference for syntax elements shared by C++/CX and
C++/CLI.

Universal Windows Apps (C++) Write UWP applications using C++/CX or Windows Runtime
Template Library (WRL).

C++ Attributes for COM and .NET Non-standard attributes for Windows-only programming
using .NET or COM.
Universal Windows Apps (C++)
9/21/2021 • 2 minutes to read • Edit Online

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 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 10 SDK from version
1803 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++
3/6/2021 • 2 minutes to read • Edit Online

When you create a Windows 10 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 10
games thrill players of all ages and genres. The new Universal Windows Platform (UWP) delivers compatibility
for your game across Windows 10 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.
.NET programming with C++/CLI
9/22/2021 • 2 minutes to read • Edit Online

By default, CLR projects created with Visual Studio 2015 target .NET Framework 4.5.2. You can target .NET
Framework 4.6 when you create a new project. In the New Project dialog, change the target framework in the
dropdown at the top middle of the dialog. To change the target framework for an existing project, close the
project, edit the project file ( .vcxproj ), and change the value of the Target Framework Version to 4.6. The
changes take effect the next time you open the project.
In Visual Studio 2017, the default target .NET Framework is 4.6.1. The Framework version selector is at the
bottom of the New Project dialog.

Install C++/CLI support in Visual Studio 2017


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 Star t 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 suppor t . Select Modify to download the necessary files and update Visual Studio.
In Visual Studio 2019, the default target framework for .NET Core projects is 5.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 2019


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 Star t 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 suppor t for v142 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++
9/21/2021 • 2 minutes to read • Edit Online

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
9/21/2021 • 3 minutes to read • Edit Online

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 2015-2019.
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
T IT L E DESC RIP T IO N

Upgrading C++ projects from earlier versions of Visual How to upgrade your code base to Visual Studio 2019 and
Studio v142 of the compiler.

IDE tools for upgrading C++ code Useful IDE features that help in the upgrade process.

C++ binary compatibility 2015-2019 Consume v140 and v141 libraries as-is from v142 projects.

Use native multi-targeting in Visual Studio to build old Use Visual Studio 2019 with older compilers and libraries.
projects

Visual C++ change history 2003 - 2015 A list of all the changes in the Microsoft C++ libraries and
build tools from Visual Studio 2003 through 2015 that
might require changes in your code.

Visual C++ What's New 2003 through 2015 All the "what's new" information for Microsoft C++ from
Visual Studio 2003 through Visual Studio 2015.

Porting and Upgrading: Examples and Case Studies For this section, we ported and upgrades several samples
and applications and discussed the experiences and results.
These articles give you a sense of what's involved in the
porting and upgrading process. Throughout the process, we
discuss tips and tricks for upgrading and show how specific
errors were fixed.

Porting to the Universal Windows Platform Contains information about porting code to Windows 10

Introduction to Visual C++ for UNIX Users Provides information for UNIX users who are new to Visual
C++ and want to become productive with it.

Running Linux programs on Windows Discusses options for migrating UNIX applications to
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++
3/6/2021 • 3 minutes to read • Edit Online

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
3/6/2021 • 2 minutes to read • Edit Online

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
7/28/2021 • 2 minutes to read • Edit Online

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
3/6/2021 • 20 minutes to read • Edit Online

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):
// 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:

T RUST B O UN DA RY DESC RIP T IO N

Virtual machine boundary Applications that isolate workloads in separate virtual


machines that receive untrusted data from another virtual
machine may be at risk.

Kernel boundary A kernel-mode device driver that receives untrusted data


from a non-administrative user mode process may be at
risk.

Process boundary An application that receives untrusted data from another


process running on the local system, such as through a
Remote Procedure Call (RPC), shared memory, or other
Inter-Process Communication (IPC) mechanisms may be at
risk.

Enclave boundary An application that executes within a secure enclave (such as


Intel SGX) that receives untrusted data from outside of the
enclave may be at risk.

Language boundary An application that interprets or Just-In-Time (JIT) compiles


and executes untrusted 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.

// 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.

// 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.
#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.

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.

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.

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 .
// 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 .

#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:

SP EC UL AT IO N B A RRIER IN T RIN SIC SP EC UL AT IO N B A RRIER IN T RIN SIC


A RC H IT EC T URE F O R C VE- 2017- 5753 F O R C VE- 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.

// 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.
// 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
9/21/2021 • 2 minutes to read • Edit Online

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.
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.
Languages
3/6/2021 • 2 minutes to read • Edit Online

C Language
C++ Language
C/C++ Preprocessor
Compiler Intrinsics and Assembly Language
C Language Reference
3/6/2021 • 2 minutes to read • Edit Online

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
3/6/2021 • 2 minutes to read • Edit Online

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
11/2/2020 • 2 minutes to read • Edit Online

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
3/6/2021 • 2 minutes to read • Edit Online

This section of the documentation contains information about compiler intrinsics and the assembly language.

Related articles
T IT L E DESC RIP T IO N

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 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).

C++ in Visual Studio The top-level article for Visual C++ documentation.
Compiler intrinsics
3/6/2021 • 2 minutes to read • Edit Online

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
8/25/2021 • 2 minutes to read • Edit Online

The articles in this section of the documentation provide reference material for the Microsoft ARM assembler
(armasm) and related tools.

Related Articles
T IT L E DESC RIP T IO N

ARM Assembler Command-Line Reference Describes the armasm command-line options.

ARM Assembler Diagnostic Messages Describes commonly seen armasm warning and error
messages.

ARM Assembler Directives Describes the ARM directives that are different in armasm.

ARM Architecture Reference Manual on the ARM Developer Choose the relevant manual for your ARM architecture. Each
website. contains reference sections about ARM, Thumb, NEON, and
VFP, and additional information about the ARM assembly
language.

ARM Compiler armasm User Guide on the ARM Developer Choose a recent version to find up-to-date information
website. about the ARM assembly language.

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
3/6/2021 • 2 minutes to read • Edit Online

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).

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
9/22/2021 • 2 minutes to read • Edit Online

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
9/21/2021 • 5 minutes to read • Edit Online

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.

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.

K EY W O RD C O N T EXT SEN SIT IVE P URP O SE REF EREN C E

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
K EY W O RD C O N T EXT SEN SIT IVE P URP O SE REF EREN C E

enum class No Declares an enumeration. enum class

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).

K EY W O RD C O N T EXT SEN SIT IVE P URP O SE REF EREN C E

abstract Yes Indicates that functions or abstract


classes are abstract.

new No Indicates that a function is new (new slot in vtable)


not an override of a base
class version.

override Yes Indicates that a method override


must be an override of a
base-class version.

sealed Yes Prevents classes from being sealed


used as base classes.

Keywords for Generics


The following keywords have been added to support generic types. For more information, see Generics.

K EY W O RD C O N T EXT SEN SIT IVE P URP O SE

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.
K EY W O RD C O N T EXT SEN SIT IVE P URP O SE REF EREN C E

finally Yes Indicates default exception Exception Handling


handlings behavior.

for each, in No Enumerates elements of a for each, in


collection.

gcnew No Allocates types on the ref new, gcnew


garbage-collected heap.
Use instead of new and
delete .

ref new Yes Allocates a Windows ref new, gcnew


Runtime type. Use instead
of new and delete .

initonly Yes Indicates that a member initonly (C++/CLI)


can only be initialized at
declaration or in a static
constructor.

literal Yes Creates a literal variable. literal

nullptr No Indicates that a handle or nullptr


pointer does not point at
an 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.

K EY W O RD P URP O SE REF EREN C E

array Declares an array. Arrays

interior_ptr (CLR only) Points to data in a reference interior_ptr (C++/CLI)


type.

pin_ptr (CLR only) Points to CLR reference pin_ptr (C++/CLI)


types to temporarily suppress the
garbage-collection system.

safe_cast Determines and executes the optimal safe_cast


casting method for a runtime type.

typeid (CLR only) Retrieves a System.Type typeid


object that describes the given type or
object.

Declarators
The following type declarators instruct the runtime to automatically manage the lifetime and deletion of
allocated objects.

O P ERATO R P URP O SE REF EREN C E

^ Declares a handle to an object; that is, Handle to Object Operator (^)


a pointer to a Windows Runtime or
CLR object that is automatically
deleted when it is no longer usable.

% Declares a tracking reference; that is, a Tracking Reference Operator


reference to a Windows Runtime or
CLR object that is automatically
deleted when it is no longer usable.

Additional Constructs and Related Topics


This section lists additional programming constructs, and topics that pertain to the CLR.

TO P IC DESC RIP T IO N

__identifier (C++/CLI) (Windows Runtime and CLR) Enables the use of keywords as
identifiers.

Variable Argument Lists (...) (C++/CLI) (Windows Runtime and CLR) Enables a function to take a
variable number of arguments.

.NET Framework Equivalents to C++ Native Types (C++/CLI) Lists the CLR types that are used in place of C++ integral
types.

appdomain __declspec modifier __declspec modifier that mandates that static and global
variables exist per appdomain.

C-Style Casts with /clr (C++/CLI) Describes how C-style casts are interpreted.

__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 Traits Discusses how to detect characteristics of types at compile
time.
TO P IC DESC RIP T IO N

managed, unmanaged pragmas Demonstrates how managed and unmanaged functions can
co-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.

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
7/28/2021 • 4 minutes to read • Edit Online

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.

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.

[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 Proper ties 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.

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
Debugging 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.

In This Section
Attribute Programming FAQ
Attributes by Group
Attributes by Usage
Attributes Alphabetical Reference
Libraries
5/10/2021 • 2 minutes to read • Edit Online

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
3/9/2021 • 2 minutes to read • Edit Online

The Microsoft runtime library provides routines for programming the Microsoft Windows operating system.
These routines automate many common programming tasks that are not provided by the C and C++ languages.
Sample programs are included in the individual reference topics 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
3/9/2021 • 2 minutes to read • Edit Online

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.

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
3/6/2021 • 2 minutes to read • Edit Online

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
SEC T IO N DESC RIP T IO N

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
SEC T IO N DESC RIP T IO N

C++ Language Reference Reference and conceptual content for the C++ language.
SafeInt Class
3/6/2021 • 9 minutes to read • Edit Online

Extends the integer primitives to help prevent integer overflow and lets you compare different types of integers.

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
template<typename T, typename E = _SAFEINT_DEFAULT_ERROR_POLICY>
class SafeInt;

Parameters
T
The type of integer or Boolean parameter that SafeInt replaces.
E
An enumerated data type that defines the error handling policy.
U
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
NAME DESC RIP T IO N

SafeInt::SafeInt Default constructor.

Assignment Operators
NAME SY N TA X
NAME SY N TA X

= 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
NAME SY N TA X

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

__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
NAME SY N TA X

< template<typename U>

bool operator< (U rhs) const throw()

< bool operator< (SafeInt<T,E> rhs) const throw()


NAME SY N TA X

>= 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()

== 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
NAME SY N TA X

+ 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


NAME SY N TA X

%= 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)

*= 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)


NAME SY N TA X

+= 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)

-= template<typename U>

SafeInt<T,E>& operator-= (SafeInt<U, E> rhs)

Logical Operators
NAME SY N TA X

! 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()


NAME SY N TA X

>> 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()

& 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&#124; (SafeInt<T,E> rhs)


const throw()
NAME SY N TA X

| template<typename U>

SafeInt<T,E> operator&#124; (U rhs) const throw()

|= SafeInt<T,E>& operator&#124;= (SafeInt<T,E> rhs)


throw()

|= template<typename U>

SafeInt<T,E>& operator&#124;= (U rhs) throw()

|= template<typename U>

SafeInt<T,E>& operator&#124;= (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> .

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.

Int x = flag ? SafeInt<unsigned int>(y) : -1;

The compiler converts it to this:

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.

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.

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.

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

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

#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.

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
3/6/2021 • 5 minutes to read • Edit Online

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.

NOTE
The latest version of this library is located at https://github.com/dcleblanc/SafeInt.

In This Section
F UN C T IO N DESC RIP T IO N

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, SafeGreaterThanEquals, Compares two numbers. These functions enable you to
SafeLessThan, SafeLessThanEquals, SafeNotEquals compare two different types of numbers without 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
SEC T IO N DESC RIP T IO N

SafeInt The SafeInt class.

SafeIntException The exception class specific to the SafeInt library.

SafeAdd
Adds two numbers in a way that protects against overflow.

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.

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.

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.

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.

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.

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.

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.
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.

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.

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.

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.

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
3/6/2021 • 2 minutes to read • Edit Online

The SafeInt class uses SafeIntException to identify why a mathematical operation cannot be completed.

NOTE
The latest version of this library is located at https://github.com/dcleblanc/SafeInt.

Syntax
class SafeIntException;

Members
Public Constructors
NAME DESC RIP T IO N

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.

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
9/21/2021 • 2 minutes to read • Edit Online

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
T IT L E DESC RIP T IO N

MFC Desktop Applications Microsoft Foundation Classes provide a thin object-oriented


wrapper over Win32 to enable rapid development of GUI
applications in C++.

ATL COM Desktop Components ATL provides class templates and other use constructs to
simplify creation of COM objects in C++.

ATL/MFC Shared Classes References for CStringT Class and other classes that are
shared by MFC and ATL.

Working with Resource Files The resource editor lets you edit UI resources such as
strings, images, and dialog boxes.

C++ in Visual Studio Parent topic for all C++ documentation.


Parallel Programming in Visual C++
9/21/2021 • 2 minutes to read • Edit Online

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
T IT L E DESC RIP T IO N

Auto-Parallelization and Auto-Vectorization Compiler optimizations that speed up code.

Concurrency Runtime Classes that simplify the writing of programs that use data
parallelism or task parallelism.

C++ AMP (C++ Accelerated Massive Parallelism) Classes that enable the use of modern graphics processors
for general purpose programming.

Multithreading Support for Older Code (Visual C++) Older technologies that may be useful in older applications.
For 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++
3/6/2021 • 2 minutes to read • Edit Online

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