Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/MicrosoftDocs/cpp-docs/llms.txt

Use this file to discover all available pages before exploring further.

Visual Studio makes upgrading C++ projects between toolset versions straightforward for most codebases. Projects created in Visual Studio 2010 through 2017 typically open and build in the latest Visual Studio with only a retargeting step. The key insight is that Visual Studio 2015 through 2026 all use MSVC build tools with major version 14 (v140–v145), and binaries produced by these toolsets are binary-compatible — you can link object files and libraries built with any of these versions without recompilation. Understanding what has changed between versions, and which automated tools can help, makes the upgrade process significantly less daunting.

Quick Start: Retargeting Your Project

When you open an older .vcxproj or .sln in a newer Visual Studio, a Retarget Projects dialog appears, offering to upgrade the Platform Toolset and Windows SDK version.
1

Open the Solution

Open your .sln file in the latest Visual Studio. If the Retarget dialog does not appear, right-click the solution in Solution Explorer → Retarget Solution.
2

Select Toolset and SDK

Choose the latest Platform Toolset (e.g., v143 for VS 2022, v145 for VS 2026) and the latest installed Windows SDK version.
<!-- After retargeting, .vcxproj changes from: -->
<PlatformToolset>v120</PlatformToolset>
<!-- to: -->
<PlatformToolset>v143</PlatformToolset>
3

Build and Address Errors

Build the solution. Most projects compile cleanly. Remaining errors typically fall into a few categories: deprecated functions, stricter conformance, changed standard library behavior, or removed Win32 APIs.
4

Run Tests

Run your existing test suite. Pay special attention to numeric/floating-point computations, where the newer toolset may produce slightly different results due to stricter IEEE 754 compliance.

Binary Compatibility: Visual Studio 2015–2026

One of the most significant improvements in modern MSVC is ABI stability across major releases. All toolsets from VS 2015 (v140) through VS 2026 (v145) produce binaries that can be linked together without recompilation, provided you use dynamically linked CRT (/MD).
Visual Studio 2015 → v140  (14.0.x)
Visual Studio 2017 → v141  (14.1.x)
Visual Studio 2019 → v142  (14.2.x)
Visual Studio 2022 → v143  (14.3.x)
Visual Studio 2026 → v145  (14.5.x)
// A library built with VS 2015 /MD can be linked into a VS 2026 application:
// lib_2015.lib   (built with v140, /MD) ← works with VS 2026 linker
// app_2026.exe   (built with v143, /MD) ← can link lib_2015.lib
ABI compatibility requires /MD (dynamic CRT). Static CRT (/MT) is NOT ABI-compatible across toolset versions. Also, binaries compiled with /GL (Whole Program Optimization) are not binary-compatible even across minor version updates of the same major toolset.

Restrictions on Binary Compatibility

When linking binaries built with different toolset versions, the linker must be at least as new as the newest component. For example, if you have a library from VS 2019 (v142) and an app from VS 2017 (v141), you must link with VS 2019 or later.
Object files and static libraries compiled with /GL (Whole Program Optimization) or linked with /LTCG are only compatible with the exact same build tools version — including minor updates. Even a patch release can cause linker error C1047.
# This combination will fail if the versions differ:
cl /GL /O2 mylib.cpp
link /LTCG mylib.obj   # Must use same cl.exe version

Upgrading from Visual Studio 2008 and Earlier

For projects predating VS 2010, use the two-step approach:
VS 2008 project → Open in VS 2010 (upgrades to MSBuild .vcxproj format)
                → Then open in latest Visual Studio (retarget toolset)
VCBuild (.vcproj format from VS 2008 and earlier) cannot be directly imported by VS 2015 or later. VS 2010 performs the conversion to MSBuild format, which all modern versions support.

Common Porting Issues

Deprecated CRT Functions

MSVC deprecates POSIX-named CRT functions (without the underscore prefix) and classic unsafe functions:
// DEPRECATED — triggers C4996 warning:
access("file.txt", 0);     // Use _access instead
unlink("file.txt");        // Use _unlink instead
strdup(str);               // Use _strdup instead
getcwd(buf, size);         // Use _getcwd instead
strcpy(dest, src);         // Use strcpy_s instead
sprintf(buf, fmt, ...);    // Use sprintf_s instead

// CORRECT replacements:
_access("file.txt", 0);
_unlink("file.txt");
_strdup(str);
_getcwd(buf, size);
strcpy_s(dest, sizeof(dest), src);
sprintf_s(buf, sizeof(buf), fmt, ...);

Stricter Conformance — /permissive-

VS 2017 and later default to stricter C++ conformance mode. Code that relied on MSVC extensions may fail to compile:
// Non-standard: two-phase name lookup not previously enforced
template<typename T>
void foo() {
    bar(); // In /permissive- mode, 'bar' must be declared before the template
}

// Fix: forward-declare bar() before the template definition
void bar();
template<typename T>
void foo() { bar(); }
# Temporarily relax conformance during transition:
cl /permissive myfile.cpp

# Full conformance mode (default in newer toolsets):
cl /permissive- myfile.cpp

Changed std:: Behavior

Some standard library implementations became stricter or changed behavior:
// VS 2015+: std::bind no longer allows nested bind expressions
// without explicit std::ref wrapping

// VS 2017+: std::vector<bool> is no longer assignable in certain contexts

// Use explicit types to avoid ambiguity:
std::vector<bool> flags = {true, false, true};
bool val = static_cast<bool>(flags[0]); // Explicit cast required in some contexts

Pragma and __declspec Changes

// Suppressing specific warnings during transition:
#pragma warning(push)
#pragma warning(disable: 4996) // 'function': deprecated
#include <legacy_header.h>
#pragma warning(pop)

// Or per-file via project properties:
// C/C++ → Advanced → Disable Specific Warnings: 4996

Universal CRT Upgrade

VS 2015 split the legacy msvcr120.dll into the Universal CRT (ucrtbase.dll) and vcruntime140.dll. Code that directly called internal CRT symbols may break:
// BROKEN: Direct use of internal CRT symbols (not public API)
extern "C" int _cdecl __stdio_common_vfprintf(...);

// FIX: Use the public API — printf, fprintf, etc.
printf("%s\n", message);

IDE Tools for Upgrading

Visual Studio provides several tools to assist upgrades:

Upgrade Wizard

Right-click solution → Retarget Solution to change the Platform Toolset and Windows SDK version across all projects at once.

Error List Filtering

Use the Error List Search box to filter errors by warning code (e.g., C4996) and address them systematically.

/analyze (Code Analysis)

Enable static analysis with /analyze to catch deprecated patterns, security issues, and conformance problems before they become runtime errors.

Dependency Walker

Use dumpbin /dependents myapp.exe or Dependency Walker to verify which runtime DLLs your upgraded binary requires.

GitHub Copilot Modernization for C++

Visual Studio 2026 includes GitHub Copilot modernization for C++, an AI agent that automates the upgrade workflow. It upgrades project settings, builds the project, analyzes errors, proposes fixes, and iterates until the build succeeds.
1

Enable the Feature

Copilot modernization is enabled by default in VS 2026. To toggle it: Tools → Options → All Settings → GitHub → Copilot → C/C++ → check Enable GitHub Copilot modernization for C++ (preview).
2

Start the Modernize Agent

Right-click your solution in Solution Explorer → Modernize. This opens GitHub Copilot Chat with the agent pre-activated and ready-to-use prompts displayed.Alternatively, open Copilot Chat (View → GitHub Copilot Chat) and type:
Use @Modernize to update MSVC Build Tools.
3

Review and Approve Changes

The agent presents a step-by-step plan showing which files it will modify. Review the diff for each change before approving. The agent then applies changes, rebuilds, and iterates on remaining errors.
GitHub Copilot modernization for C++ supports both MSBuild-based projects (.sln, .vcxproj) and CMake-based projects. It requires a GitHub Copilot subscription and Visual Studio 2026 version 18.3 or later. The feature is currently in preview.

Native Multi-Targeting

You can continue to build for older toolsets from within the latest Visual Studio using native multi-targeting:
<!-- .vcxproj: Target an older toolset while using the latest IDE -->
<PropertyGroup>
  <PlatformToolset>v140</PlatformToolset>  <!-- VS 2015 toolset -->
</PropertyGroup>
This allows you to maintain a legacy build configuration for existing deployments while developing with the latest IDE features, without installing an older Visual Studio.

Build docs developers (and LLMs) love