Anders Schau Knatten from C++ on a Friday
Microsoft has five different version numbers to think about when it comes to C++. Here’s an attempt to explain what they all mean.
- Visual Studio release year (the “marketing version number”), e.g. Visual Studio 2022
- Visual Studio actual version number, e.g. Visual Studio 17.0
- Visual C++ (MSVC) version, e.g. MSVC 14.30
- Toolset version, e.g. toolset 143
- Compiler version, e.g.
Visual Studio versions
What most people will see first is the Visual Studio release year. You’ll download Visual Studio 2022, Visual Studio 2019 etc. These however also have a more normal major.minor versioning scheme, and they bump the major version for every release year. So for instance VS 2017 is version 15, VS 2019 is version 16, and VS 2022 is version 17. Note that the year and the major version are not correlated in any way, except that Visual Studio 2010 just happened to also be version 10.
Visual Studio also has minor releases of each major version. Some examples (there are more minor releases per major than shown here):
|Visual Studio 2017||15.0|
|Visual Studio 2019||16.0|
|Visual Studio 2022||17.0|
Visual C++ versions
Microsoft Visual C++, aka MSVC, ships as a part of Visual Studio, but has its own versioning scheme. Importantly, the major number signifies ABI compatibility, so something compiled with MSVC at one major version number can be linked against something compiled with any other MSVC at the same major version. (Some restrictions apply.) The MSVC major version number luckily gets bumped a lot less often than the Visual Studio version itself. As of Visual Studio 2015, they have kept the MSVC major version at 14. The first digit of the minor version seems to be bumped for each major version of Visual Studio itself. The Visual C++ version number is also used for the Visual C++ Redistributable.
|VS Year||VS version||MSVC version|
|Visual Studio 2017||15.0||14.1|
|Visual Studio 2019||16.0||14.20|
|Visual Studio 2022||17.0||14.30|
C++ toolset versions
Closely related to the MSVC version number is the C++ toolset version number. I can’t find a good source for it, but from Microsoft’s article it seems that the toolset version is made up of the MSVC major version and the first digit of the MSVC minor version. Some examples:
|VS Year||VS version||MSVC version||Toolset version|
|Visual Studio 2017||15.0||14.1||141|
|Visual Studio 2019||16.0||14.20||142|
|Visual Studio 2022||17.0||14.30||143|
The linker (
link.exe) also uses the C++ toolset version number as its version number, so e.g. for toolset 14.32 I might see
Finally, there’s the compiler version, which is what
cl.exe reports. E.g.
19.16.27048. The major.minor version scheme correlates with the
_MSC_VER macro which you can check in your source code (godbolt). So e.g.
cl.exe version 19.21 has
_MSC_VER 1921. (I’ll be nice and count those as one version number.)
|VS Year||VS version||MSVC version||Toolset version||Compiler version|
|Visual Studio 2017||15.0||14.1||141||19.10|
|Visual Studio 2019||16.0||14.20||142||19.20|
|Visual Studio 2022||17.0||14.30||143||19.30|
_MSC_VER version number is incremented monotonically at each Visual C++ toolset update, so if you want to only compile some stuff if the compiler is new enough, you can do e.g.
#if _MSC_VER >= 1930.
Appendix: Running out of version numbers
Interestingly, the scheme where they bump the first digit of the Visual C++ minor version for each major release of Visual Studio means that they can only have nine minor versions of MSVC per Visual Studio major version! And looking at wikipedia, it seems they actually ran out of toolset versions at the end of Visual Studio 2019 and reused 14.28 and 14.29 for the final four Visual Studio 2019 releases (Visual Studio 16.8 and 16.9 had MSVC 14.28, Visual Studio 16.10 and 16.11 had MSVC 14.29).