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
}
#endif

Important 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.