跳转到主内容
趣航编程网 - 趣学编程,启航技术之路!

C++如何根据宏定义判断系统当前的编译器版本对照表 _ 跨平台汇总【干货】

最可靠方式是按优先级顺序检测预定义宏:先判 _MSC_VER(MSVC 或 clang-cl),再判 __clang__(原生 Clang),最后判 __GNUC__(GCC/MinGW);版本判断须用对应宏区间比较,避免硬匹配或依赖非稳定宏。 直接用预定义宏判断编译器版本最可靠,但必须按优先级顺序检测、用区间比较、避开不稳定宏——否则在 Clang on Windows 或 MinGW 环境下极易误判。 如何正确区分 GCC / Clang / MSVC 编译器类型 不能只靠
__GNUC__
__clang__
单独存在来断定编译器:
_MSC_VER
一旦被定义,就代表当前是 MSVC 或 clang-cl 模式(ABI/头文件兼容),应立即终止后续判断
__clang__
在 Windows 上常和
_MSC_VER
同时存在;只有当
_MSC_VER
未定义而
__clang__
存在时,才是原生 Clang
__GNUC__
仅在前两者都未定义时才可视为 GCC 或 MinGW-GCC 典型误判场景:Clang on Windows 项目里写
#if defined(__clang__) && !defined(_MSC_VER)
,结果跳过 MSVC 兼容路径,导致 STL 行为不一致。 GCC 版本判断:必须用
__GNUC__
系列做区间比较
__GNUC__
__GNUC_MINOR__
__GNUC_PATCHLEVEL
是 GCC 工具链唯一稳定可用的整数宏,值可安全用于数值比较: 立即学习 “ C++免费学习笔记(深入) ”; C知道 CSDN推出的一款AI技术问答工具 下载 写
#if __GNUC__ >= 12
表示支持 GCC 12.x 及以上(含 12.1、12.4) 写
#if __GNUC__ > 11 || (__GNUC__ == 11 && __GNUC_MINOR__ >= 3)
表示 ≥ 11.3 避免硬匹配:
#if __GNUC__ == 12
会漏掉 12.1,且无法适配未来补丁更新 别单独依赖
__GNUC__
判断 C++ 特性——GCC 10 和 11 对
__cpp_concepts
支持程度不同,建议结合特性宏验证 MSVC 和 Clang 版本判断的关键差异 MSVC 唯一可信宏是
_MSC_VER
(如 VS2019=1920,VS2022=1930),它在 clang-cl 下也会被定义,这反而是优势: 用
#if _MSC_VER >= 1930
可安全启用 VS2022+ 新增的
std::span
constexpr 构造等 STL 特性 绝对不要用
_MSC_FULL_VER
——它含构建号,值跳跃无规律,CI 中易因 Update 版本不同而失效 Clang 应优先用
__clang_major__
/
__clang_minor__
,而非仅靠
__clang__
(它只是布尔标记,不带版本信息) Clang on Windows 若启用了
/Zc:__cplusplus
__cplusplus
值可能被强制设为 201703L,此时不能单靠它推断语言能力 C++ 标准版本宏的跨平台陷阱
__cplusplus
在 GCC/Clang 下反映编译选项(如
-std=c++17
),但在 MSVC 下默认不更新——需手动开启
/Zc:__cplusplus
或依赖
_MSVC_LANG
: MSVC 推荐统一用
_MSVC_LANG
(如
#if _MSVC_LANG >= 201703L
),它比
__cplusplus
更可靠 Clang/GCC 下仍以
__cplusplus
为准,但要注意:某些旧版 Clang(如 3.5)即使加了
-std=c++14
__cplusplus
仍返回 201103L 混合项目中,若同时检测
__cplusplus
_MSC_LANG
,务必先判断编译器类型,再选对应宏,否则逻辑错乱 最易忽略的一点:宏值只表示“编译器声称支持的标准”,不代表实际实现了所有特性——比如 GCC 8.2 声称支持 C++17,但
std::optional
需要额外链接
-lstdc++fs
才能用。真要用某个特性,最好搭配
__has_include
__cpp_xxx
特性宏二次确认。

相关文章