Official documentation on Predefined Macros in Visual C++
This blog was written by Gabriel Dos Reis and Mark Levine.
Starting with VS “15” Preview 5, the Visual C++ Team is monotonically updating the value of the built-in preprocessor macro
_MSC_VER at every Visual C++ toolset update.
Thanks to the investments and progress that the Visual C++ Team has been making in the area of ISO C++ implementation conformance, we have been shipping new language features and introducing new conformance changes at a pace never seen before by our customers, in particular in updates to the Visual C++ toolset. As a result, it has become necessary for our customers to have a good way to differentiate between updates of VC++ (and not just major versions) within their source code. For instance, a program wanting to make use of the C++11 noexcept feature with VC++ would typically write:
#if _MSC_VER >= 1900 // … use noexcept here … #endif
How to Test?
Traditionally, developers write conditionally-included pieces of code testing the value of the built-in preprocessor macro
_MSC_VER against known values indicating major releases of the Visual C++ compiler. For example,
_MSC_VER >= 1900
tests for any version of the Visual C++ compiler released after VS2015 RTM. That continues to be our recommended practice. What we are doing, starting with VS “15”, is to increment the value of
_MSC_VER at each update.
To test for VC++ updates or releases after a given reference point, use the “
>=” (greater-or-equal) operator to compare
_MSC_VER against that known reference value. Furthermore, if you have several reference points to compare against in a mutually exclusive manner, we recommend you order your comparisons in decreasing order of the reference values. For instance, the following snippet
#if _MSC_VER >= 1900 // … #elif _MSC_VER >= 1800 // … #else // … #endif
checks for compilers released after VS2015, then compilers released after VS2013, then takes an action for all compilers released prior to VS2013.
Ordering Tests with <
If you chose to use the less-than operator (
<), then we recommend that you order your tests in increasing order of the reference values.
Checking for A Specific Compiler Version
On very rare occasions, you might be looking for a specific VC++ release. Only in such circumstances would you need to use the equality operator “
==” to compare
_MSC_VER against a known value. Such circumstances include working around a bug in a well-known version of VC++. However, in general, we recommend you use the “
>=” and order your tests in decreasing order.
Looking for A Closed Set of Compiler Versions
Some circumstances require looking for a closed set of compiler versions. For instance, this code fragment
#if _MSC_VER >= 1900 && _MSC_VER < 2000 “mspdb140.dll” #endif
includes the string literal
“mspdb140.dll” only when the compiler is from the VS2015 vintage. In these situations, you will use “
>=” and “
<” to construct a semi-open interval that delimits the release series you are interested in.
When Should I Use _MSC_FULL_VER Then?
_MSC_FULL_VER is a more granular variant of the built-in preprocessor macro
_MSC_VER that incorporates also the build number of the compiler. You would use this when you want to differentiate between micro-updates of the same update. Until now, it has also been used to differentiate between updates.
What About _MSC_BUILD?
It is a built-in preprocessor macro, documented here, rarely used or needed in most C or C++ source code.
The Compiler Versioning Scheme
Each major release of the Visual C++ compiler increments the “hundreds” of
_MSC_VER. Each update within a major release increments the “units” by 1. For example, in VS “15” Preview 5, the macro
_MSC_VER evaluates to 1910. The next update will have
_MSC_VER set to 1911.
Note that VS “15” and VS2015 are both major releases of Visual Studio with different major version numbers. The included compiler toolset, however, will have the same major version number – with the change described here, the minor version number can be used to distinguish compiler toolsets.
Call to Action
If you have existing code that compares
_MSC_VER using the equality operator, have a second look and see if that comparison is better expressed with the greater-or-equal operator as explained above.