Is there a standard definition for __cplusplus in c++14?

Solution 1:

N3936* §16.8 [cpp.predefined]/p1:

1 The following macro names shall be defined by the implementation:

__cplusplus

The name __cplusplus is defined to the value 201402L when compiling a C++ translation unit.

N3936 is the final working draft that became C++14, and the number 201402L is consistent with the meeting at which the C++14 standard is sent out for final balloting (February 2014).

*Those interested in obtaining a copy of the C++ standard should check out Where do I find the current C or C++ standard documents?

Solution 2:

cppreference has information on the standard values of the __cplusplus macro in the section "Predefined macros." Currently the standard values are:

199711L (C++98 or C++03)
201103L (C++11)
201402L (C++14)
201703L (C++17)
202002L (C++20)

The macro's value for any given version isn't firmly established until the final standard is published. Therefore, as of June 2019, there was no way to know what the macro value for C++2a would be (and as of Feb 2021 there's no way to know what the value will be for C++2b).

Library vendors typically gate their "C++2a" features on #if __cplusplus > 201703L, and their "C++2b" features on __cplusplus > 202002L, and so on.

Compiler vendors with a "C++2a" mode simply picked any arbitrary value for __cplusplus that made the library vendors' checks happy:

GCC (8.x thru 10.x) -std=c++2a mode uses __cplusplus == 201709L.
Clang (5.x thru 9.x) -std=c++2a mode uses __cplusplus == 201707L.
Microsoft Visual Studio (19.20 thru 19.28) /std:c++latest mode uses __cplusplus == 201705L if and only if you pass /Zc:__cplusplus! Otherwise it uses 199711L. So watch out for that!

How have transitions historically been handled?:

Clang 4.0.1 -std=c++1z set __cplusplus == 201406L. Clang 5.0.0 introduced -std=c++17 and -std=c++2a, made -std=c++1z a synonym for -std=c++17, and bumped the macro (no matter which of 17/1z you used) to the standard value 201703L. Clang 10.0 introduced -std=c++20, made -std=c++2a a synonym for -std=c++20, and bumped the macro to the standard value 202002L. As of Feb 2021, Clang has no formal "C++2b" mode.

GCC 5.1 introduced -std=c++1z and -std=c++17 as synonyms out of the gate, setting __cplusplus == 201500L. GCC 7.1 bumped the value (no matter which spelling you used) to the standard value of 201703L. GCC 8.1 introduced -std=c++2a with __cplusplus == 201709L. GCC 10.1 introduced -std=c++20 as a synonym for -std=c++2a (but left the macro at 201709L). As of Feb 2021, GCC trunk has introduced -std=c++2b with __cplusplus == 202100L.

Oddly, according to Godbolt Compiler Explorer, MSVC bumped the macro for -std:c++latest mode from 201704L to 201705L sometime between MSVC 19.16 and 19.20. As of Feb 2021, as far as I know, MSVC has no formal "C++20" mode.