MSVC now correctly reports __cplusplus

Andrew Pardoe

The MSVC compiler’s definition of the __cplusplus predefined macro leaps ahead 20 years in Visual Studio 2017 version 15.7 Preview 3. This macro has stubbornly remained at the value “199711L”, indicating (erroneously!) that the compiler conformed to the C++98 Standard. Now that our conformance catch-up work is drawing to a close we’re updating the __cplusplus macro to reflect the true state of our implementation. The value of the __cplusplus macro doesn’t imply that we no longer have any conformance bugs. It’s just that the new value is much more accurate than always reporting “199711L”.

/Zc:__cplusplus

You need to compile with the /Zc:__cplusplus switch to see the updated value of the __cplusplus macro. We tried updating the macro by default and discovered that a lot of code doesn’t compile correctly when we change the value of __cplusplus. We’ll continue to require use of the /Zc:__cplusplus switch for all minor versions of MSVC in the 19.xx family.

The version reported by the __cplusplus macro also depends upon the standard version switch used. If you’re compiling in C++14 mode the macro will be set to “201402L”. If you compile in C++17 mode the macro will be set to “201703L”. And the /std:c++latest switch, used to enable features from the Standard currently in development, sets a value that is more than the current Standard. This chart shows the values of the __cplusplus macro with different switch combinations:

/Zc:__cplusplus switch /std:c++ switch __cplusplus value
Zc:__cplusplus Currently defaults to C++14 201402L
Zc:__cplusplus /std:c++14 201402L
Zc:__cplusplus /std:c++17 201703L
Zc:__cplusplus /std:c++latest 201704L
Zc:__cplusplus- (disabled) Any value 199711L
Zc:__cplusplus not specified Any value 199711L

Note that the MSVC compiler does not, and never will, support a C++11, C++03, or C++98 standards version switch. Also, the value of the __cplusplus macro is not affected by the /permissive- switch.

We’re updating IntelliSense to correctly reflect the value of __cplusplus when compiling with MSVC. We expect IntelliSense to be correct in the next preview of 15.7.

_MSC_VER and _MSVC_LANG

For finer-grained detection of changes in the MSVC toolset you can continue to use the _MSC_VER predefined macro. We have updated the value of this built-in macro with every toolset update in Visual Studio 2017 and will continue to do so.

The _MSVC_LANG predefined macro continues to report the Standard version switch regardless of the value of /Zc:__cplusplus. _MSVC_LANG is set whether or not the /Zc:__cplusplus option is enabled. When /Zc:__cplusplus is enabled, __cplusplus == _MSVC_LANG.

Please look for usage in your code

We’ve heard repeatedly from developers as we’ve gotten closer to complete conformance that we need to update the value of this macro. Now we need help from you. We tried to define __cplusplus correctly by default but discovered that a lot of code expects MSVC to always set the macro to “199711L”.

Please take a moment to search your code for references to __cplusplus and compile with the /Zc:__cplusplus switch enabled. Your code might be using this macro to determine if it’s being compiled with MSVC or Clang in MSVC-emulation mode. If your codebase is really old, it might be using this macro to determine if you’re using VC++ 6.0! Take a moment to compile with this switch enabled. We need the ecosystem to move forward so we can set __cplusplus accurately by default.

In closing

As always, we welcome your feedback. We can be reached via the comments below or via email (visualcpp@microsoft.com).

If you encounter other problems with MSVC in Visual Studio 2017 please let us know through Help > Report A Problem in the product, or via Developer Community. Let us know your suggestions through UserVoice. You can also find us on Twitter (@VisualC) and Facebook (msftvisualcpp).

Posted in C++

3 comments

Discussion is closed. Login to edit/delete existing comments.

  • Joseph Van Riper 1

     

    Why did you create a switch to make the compiler work correctly, instead of creating a switch to make the compiler work incorrectly to coddle the ‘lot of code [that] doesn’t compile correctly’ when your compiler didn’t set this properly?

    Basically, you’re penalizing people for conforming to the standard, instead of penalizing badly written code that didn’t follow the standard.

    I had to discover this through a google search. Instead, the code done improperly should have been the code that prompted someone to do a google search to find how they messed it up… so perhaps they could fix their code (or choose to use the compiler switch if there’s too much code to fix).

  • Joshua Samuel 1

    Can this please be a switch visible in the project properties GUI, so that we don’t forget about it?
    Just his this as an issue (that it _didn’t_ represent the newer standards), and relied on google to find this article about /Zc:__cplusplus
    Using VS2019.

  • S S 0

    Do it means that #define __cplusplus 199711L can’t be used any more?
    So how can people to mix the codes that used different C++ version?

Feedback usabilla icon