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).
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?
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.
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...