Microsoft C++ versions explained


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. cl.exe 19.30

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

Yearversion
Visual Studio 201715.0
15.3
Visual Studio 201916.0
16.1
Visual Studio 202217.0
17.1

source: Wikipedia

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.

Some examples:

VS YearVS versionMSVC version
Visual Studio 201715.014.1
15.314.11
Visual Studio 201916.014.20
16.114.21
Visual Studio 202217.014.30
17.114.31

source: Wikipedia

The linker (link.exe) also uses the Visual C++ version number as its version number, so e.g. for Visual C++ 14.32 I might see link.exe version 14.32.31332.0.

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 YearVS versionMSVC versionToolset version
Visual Studio 201715.014.1141
15.314.11141
Visual Studio 201916.014.20142
16.114.21142
Visual Studio 202217.014.30143
17.114.31143

Source: Microsoft

Compiler versions

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 YearVS versionMSVC versionToolset versionCompiler version
Visual Studio 201715.014.114119.10
15.314.1114119.11
Visual Studio 201916.014.2014219.20
16.114.2114219.21
Visual Studio 202217.014.3014319.30
17.114.3114319.31

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

Installing and Using GoogleTest with Visual Studio


Important note: This blog post is one of the top hits on Google for “googletest visual studio”. It is however quite old, and might no longer reflect the best way to use GoogleTest with Visual Studio. 

Google C++ Testing Framework (aka. GoogleTest) is a unittesting framework for C++. This post describes how to install it, and set it up in your project. I am using GoogleTest 1.6.0 here, but other versions should be similar. The instructions provided are for Visual Studio 2010, but 2012 should be exactly the same.

Installation

First of all, download the latest version from the GoogleTest download page, and unzip it. Inside, you will find a directory called msvc, which contains the Visual Studio solutions:

In this directory, you will find two solutions, gtest.sln, and gtest-md.sln. Which one you want depends on whether you are using a static or dynamic runtime. If you are unsure which one to use, take a look in your existing solution:

If you are using the DLL version of the runtime, use the gtest-md.sln solution, otherwise use gtest.sln. Before you open the solution though, make sure it is not read only, as Visual Studio will want to convert it to your version:

Open the solution you want, agree to convert the solution. Make sure you build it both in Debug and Release versions. The resulting libraries end up in gtest-1.6.0\msvc\gtest\Debug and gtest-1.6.0\msvc\gtest\Release, respectively. This is a good time to copy the libraries to wherever you keep libraries for your projects. The files you will need are gtestd.lib and gtest_maind.lib from the Debug directory, and gtest.lib and gtest_main.lib from the Release directory. In addition, you need all the headers from gtest-1.6.0\include. (Of course, you could just copy the entire gtest-1.6.0 directory and not care about which files you need.)

Setup for Your Project

I suggest to use one test project per production project. This makes it easy to find the tests you are looking for. Also, if your code is nicely decoupled, you might be able to link just these two projects, and not your entire solution. This can speed up your “red-green-refactor” cycle considerably. Finally, this makes it easy to exclude your test code from the final binary you ship. Here is an example from my Kjeller Software Community presentation:

Set the following properties for your test project:

  • Make sure to set up the test project to use the same runtime library as your production project (MT / MTd / MD / MDd).
  • Add an additional include directory c:\wherever\you\put\gtest\include
  • Add an additional library directory c:\wherever\you\put\the\libs
  • Under Linker -> Input , add a dependency on gtest.lib for your Release configuration, and gtestd.lib for your Debug configuration. Unless you want to write your own main function that runs all the tests, also add a dependency on gtest_main.lib / gtest_maind.lib, respectively. This will add a main() method to your project which discovers and runs all the tests.
  • Under Properties -> Linker -> System, set SubSystem to Console, to keep the test-window open after the tests have run.

Also make sure that your test project depends on the production project:

And that’s it! Now you can start writing and running tests, but since the documentation already describes that pretty well, I will not go into that here. If you want to have a look at the code from my Kjeller Software Community demo, it is available on GitHub.

If you enjoyed this post, you can subscribe to my blog, or follow me on Twitter.