Check C++ Standard Version Using __cplusplus
The __cplusplus macro is a predefined preprocessor
identifier that expands to an integer literal indicating the specific
version of the C++ standard supported by the active compiler. By
comparing this macro's value against standardized date codes, developers
can determine the exact language specification in use and apply
conditional compilation. This mechanism ensures backward compatibility,
enables modern feature sets safely, and allows codebases to adapt
seamlessly across diverse toolchains and environments.
How the Value is Formatted
The C++ standard defines the value of __cplusplus using
the format yyyymmL, which denotes the year and month the
standard specification was formally finalized. Because these values are
strictly increasing integers, developers can use standard relational
operators (>=, <, etc.) within
#if directives.
The standard values correspond to the following C++ releases:
- C++98 / C++03:
199711L - C++11:
201103L - C++14:
201402L - C++17:
201703L - C++20:
202002L - C++23:
202302L
Implementing Conditional Compilation
Developers use #if preprocessor checks to guard code
that relies on language features introduced in specific standards.
#include <iostream>
int main() {
#if __cplusplus >= 202002L
std::cout << "Compiled with C++20 or later.\n";
#elif __cplusplus >= 201703L
std::cout << "Compiled with C++17.\n";
#elif __cplusplus >= 201402L
std::cout << "Compiled with C++14.\n";
#elif __cplusplus >= 201103L
std::cout << "Compiled with C++11.\n";
#else
std::cout << "Compiled with C++98 or C++03.\n";
#endif
return 0;
}This approach allows a single source file to maintain alternative
implementations—for example, employing std::string_view
when compiling under C++17 or newer, while falling back to
const std::string& for older standards.
Distinguishing C from C++
Because __cplusplus is only defined in C++ translation
units, it is commonly used to write header files compatible with both C
and C++. Checking whether the macro is defined allows headers to wrap
C++ function declarations in extern "C" blocks, preventing
name mangling when linked with C code:
#ifdef __cplusplus
extern "C" {
#endif
void shared_library_function(void);
#ifdef __cplusplus
}
#endifImportant Compiler Considerations: MSVC
While compilers like GCC and Clang automatically update
__cplusplus based on flags such as -std=c++17
or -std=c++20, Microsoft Visual C++ (MSVC) historically
defaults to reporting 199711L to preserve backward
compatibility with legacy code.
To ensure MSVC correctly reflects the targeted standard via
__cplusplus, developers must explicitly pass the
/Zc:__cplusplus compiler flag in addition to the standard
version flag (such as /std:c++17 or
/std:c++20). Without this switch, standard-version checks
relying on __cplusplus in MSVC environments may fail or
yield misleading results.