必须依赖预定义宏而非运行时检测:GCC/Clang用__clang__优先判别后取对应major/minor/patch宏,MSVC用_MSC_VER查表映射VS版本,ICC需优先检查__INTEL_LLVM_COMPILER,ICX等其他编译器各有专属宏且须按优先级顺序检测。

要准确识别C++项目在不同平台下使用的编译器及其完整版本号,必须依赖预定义宏而非运行时检测——因为编译器版本信息在预处理阶段就已固化,且不同厂商(GCC、Clang、MSVC、Intel、PGI等)的宏命名规则、数值编码方式、版本字段拆分逻辑均不相同。
识别GCC与Clang的主版本+次版本+补丁号
GCC和Clang共享__GNUC__、__GNUC_MINOR__、__GNUC_PATCHLEVEL__三宏,但Clang会额外定义__clang__,需优先判别:
方法一:先判断是否为Clang → 若定义了__clang__,则用__clang_major__、__clang_minor__、__clang_patchlevel__;否则再查__GNUC__系宏。
方法二:直接用条件嵌套——【若同时定义__clang__和__GNUC__,必须以__clang__系宏为准,否则会误报为GCC 4.2.1这类过时版本】。
立即学习“C++免费学习笔记(深入)”;
这一步操作起来很简单,直接在头文件里写#if defined(__clang__)即可进入Clang分支。
解析MSVC的完整版本:从_MSC_VER到_MSVC_LANG
MSVC不提供单独的补丁号宏,_MSC_VER仅表示主+次版本(如1930代表VS2022 17.3),需结合编译器实际发布表映射:
第一步:提取_MSC_VER高两位为年份基值(19→2019,1930→2022),低两位为小版本序号(30→17.3);
第二步:用__FUNCSIG__或/EP预处理输出验证是否启用了C++20模式——【_MSVC_LANG仅反映标准模式,不等于编译器真实版本,不可用于版本判定】;
第三步:对准微软官方《Visual Studio与_MSVC_VER对应关系表》,例如_MSC_VER==1936 → VS2022 17.6 → 编译器完整版号17.6.33323.123。
区分Intel C++ Compiler(ICC/ICPC)与ICX(基于LLVM)
方法一:ICC/ICPC使用__INTEL_COMPILER(整型,如20210 == 2021.1)、__INTEL_COMPILER_UPDATE(更新号);
方法二:ICX(Intel LLVM)定义__INTEL_LLVM_COMPILER(如20230101),此时__clang__也存在,但__INTEL_LLVM_COMPILER值格式为YYYYMMDD;
注意:不能只靠__INTEL_COMPILER存在就断定是传统ICC——【ICX会同时定义__INTEL_COMPILER和__INTEL_LLVM_COMPILER,必须优先检查后者】。
其他编译器快速对照锚点
PGI/NVIDIA HPC SDK:__PGI、__PGIC__、__PGIC_MINOR__;
ARM Compiler(armclang):__ARMCOMPILER_VERSION(格式为1001000 → 1.1.0);
IBM XL C/C++:__xlC__(浮点值,如16.1 → 1610);
TI C/C++ Compiler:__TMS320C6X__ + _TMS320C6X_VER(十六进制编码)。


















