C++14 – Standard Definition for __cplusplus

c++c++14

I'm looking to setup some preprocessor stuff, and I'd like a more exact number for what __cplusplus in C++14 should be defined as. Is there one mandated by the standard?

Best Answer

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)
202302L (C++23)

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.