__cplusplus
是 C++ 标准规定的预定义宏,用于标识编译器遵循的 C++ 语言标准版本。以下是详细解释:
1. 基本定义
- 作用:标识当前编译环境是否为 C++ 及其版本
- 定义位置:由编译器自动预定义,无需手动声明
- 值类型:长整型常量(
long
) - 检测方式:
#ifdef __cplusplus // 当前是 C++ 编译环境 #else // 当前是 C 或其他语言环境 #endif
2. 标准版本对应值
C++ 标准版本 | __cplusplus 值 | 编译器支持示例 |
---|---|---|
C++98 / C++03 | 199711L | 所有支持 C++98 的编译器 |
C++11 | 201103L | GCC 4.7+, Clang 3.3+, MSVC 2015+ |
C++14 | 201402L | GCC 5.0+, Clang 3.4+, MSVC 2017+ |
C++17 | 201703L | GCC 7.0+, Clang 5.0+, MSVC 2017+ |
C++20 | 202002L | GCC 10.0+, Clang 10.0+, MSVC 2019+ |
C++23 | 202302L | GCC 13.0+, Clang 17.0+, MSVC 2022+ |
注:MSVC 在 VS2017 前需添加
/Zc:__cplusplus
编译选项才能正确报告版本
3. 应用场景
(1) 头文件兼容 C/C++
#ifdef __cplusplus
extern "C" { // 告诉 C++ 编译器使用 C 的链接规则
#endif
// 函数声明(同时兼容 C 和 C++)
void cross_lang_func(int param);
#ifdef __cplusplus
} // 结束 extern "C" 块
#endif
作用:确保 C 代码可以调用这些函数(避免 C++ 的名称修饰)
(2) 条件编译不同版本特性
#if __cplusplus >= 202002L
// C++20 特性
#include <concepts>
template <std::integral T>
#elif __cplusplus >= 201703L
// C++17 特性
if constexpr (std::is_integral_v<T>)
#elif __cplusplus >= 201103L
// C++11 特性
static_assert(std::is_integral<T>::value, "")
#endif
4. 特殊注意事项
错误用法:
#ifdef __cplusplus == 201103L // 错误!不能这样判断
#endif
正确用法:
#if __cplusplus >= 201103L // 正确
#endif
正确用法:
#if defined(__cplusplus) // 正确
#endif
总结
- 核心作用:识别 C++ 编译环境和版本
- 关键价值:
- 编写跨 C/C++ 的代码
- 条件启用新版语言特性
- 处理编译器兼容性问题
- 实践:
// 推荐检测方式 #if defined(__cplusplus) && (__cplusplus >= 201103L) // 安全使用 C++11 特性 #endif
在大型跨平台项目中,正确使用 __cplusplus
保证代码可移植性。